React: Passing props to Component's inner function fails - javascript

I'm testing if it is possible to have a Button component which changes a 'counter' state, but the nature of the change depends on another state 'type'. Doing console log of the prop 'type' inside the Button component it appears to get correctly the content of it, but when passing it to a inner funtion 'handler', it turns to 'undefined'. Any idea of why this happens?
App.jsx
Button.jsx
Input.jsx

Should be
const handler = (type, setCounter) =>`

Related

Why does React/Typescript complain want me to use my return function in useEffect dependency array?

I'm making a checkbox component for my project, and I have it set so that whenever is isChecked state changes, useEffect will run a returnFunction (defined in the props), like so:
export function JCheckbox({ returnFunction }: JCheckboxProps) {
const [isChecked, setIsChecked] = React.useState(defaultState)
React.useEffect(() => {
returnFunction(isChecked)
}, [isChecked])
When I do this, my compiler wants me to include returnFunction in the useEffect dependency array. I'm confused why I would need to track that, it's not used at all anywhere else in the function, and it doesn't change either. The code works perfectly fine without it.
You should add your function (returnFunction) to useEffect dependency because your function reference (returnFunction) may be changed, So react ask you to add your function (returnFunction) in useEffect dependency to recognize that and update them by new function reference.
returnFunction is certainly used as it is called inside the effect, and it could certainly change as the parent component could pass in different props, in which case your component would continue to call the previously passed in function. So the linter is correct, returnFunction is a dependency. However adding it makes it slightly more difficult to detect changes of isChecked, as changing returnFunction would also trigger the effect. Thus it seems way more elegant to call returnFunction from within setIsChecked:
const [isChecked, _setIsChecked] = useState(false);
function setIsChecked(value: boolean) {
returnFunction(value);
_setIsChecked(value);
}
However in the case given it seems that the state should rather be maintained by the parent component, consider lifting it up.
returnFunction is read from props so you probably must include it in the array of dependencies.
You should almost always include every variable and function you declare inside React and use in useEffect callback in the array of dependencies.
Eslint does not expect you to include setState functions and refs that you create in the same component that you execute useEffect.
Edit:
If you have a handleChange event handler and isChecked is toggled whenever the onChange method is invoked, you probably do not need useEffect. Call returnFunction function with the new isChecked value.

ReactJS How to pass a prop to a component in state

function App() {
const [currentPanel, setCurrentPanel] = useState(ProfilePanel); // ProfilePanel is a component
return (
<div className={styles.App}>
{currentPanel}
</div>
);
}
In code i set the component "ProfilePanel" to a "curentPanlel" state, then in App i change the component in state, and this render an another panel. the problem is that i dont know how to pass props when i render it like this.
i tried the {currentPanel()} but is return an error.
please help to find a method to solve this, or if this method to render a component in state are absolutly wrong tell how to do this another way.
the problem is that i dont know how to pass props when i render it like this
You'd do it by using an initial capital letter for the state member (CurrentPanel instead of currentPanel), and then using it as normal (<CurrentPanel someProp="some value" />). (It has to be initially-capped because that's how JSX knows it's supposed to be a component, not a tag name.) But, you'll struggle to set a different component function in state, because component functions are, well, functions, and when you pass a function to a state setter, it thinks you're using the callback version of the state setter and calls your function, rather than setting it in state.
If you absolutely have to hold a component function in state, wrap it in an object, but it's much more likely that there's a better solution to the overall problem you're trying to solve.

Don't understand how JavaScript assign operator interacts with a function

My problem is that I don't understand how assign operator is interpreted and interacts with a function. Let me explain
I was changing the state of my component, and I was doing something wrong that I couldn't see until I realize it, of course.
My component:
class UpdateLifeCycle extends Component {
state = { src: urls[this.props.election] };
componentWillReceiveProps(nextProps) {
this.setState = { src: urls[nextProps.election] };
}
render() {
return (
<div>
<p>Selected {this.props.election}</p>
<img //
alt={this.props.election}
src={this.state.src}
witdh="250"
/>
<p>{urls[this.props.election]}</p>
<p>{this.state.src}</p>
</div>
);
}
}
What I was doing, and is wrong is this piece
this.setState = { src: urls[nextProps.election] };
and what I should be doing is passing it as a parameter instead of assigning it.
this.setState({ src: urls[nextProps.election] });
Why does the JS interpreter allow you to assign and object to a function, and where is that object being assigned?
TL;DR
setState is a variable which currently holds a function. There is nothing stopping you from changing its value and add an object there, because it is a variable. JavaScript was influenced by other functional programming languages and it is okay to assign a function to a variable.
Explanation
state is a special object in a React component, which you would access as this.state. setState is a special function in a React component, which allows you to modify the state. Actions are dispatched when the state is updated, however you should not directly modify the state of a React component, and should always use setState.
setState is another variable in a JavaScript class (Your React Component is a class-based component), which by default holds the function to modify the state variable.
You can override a variable in JavaScript and when you assign an object (the new state you wanted) to setState, you are changing the value of setState which can no longer now update the state variable.
You would find React's docs helpful.

ReactJS - setState fails to update property value

I have a property name in a React component. Using setState I am trying to modify this property. But assigning a new value to this property inside setState has no effect. Please find below my sample code.
export const Test = ({
name,
changeState = function (newName) {
this.setState({name: newName}, () => console.log('Name after setState # ' + name)); //prints old value
console.log(name); // Doesn't reflect changes. Prints old name
}
}) =>
(
<div>Some data</div>
)
User action will trigger a call to changeState(newName). I am calling setState inside changeState function.
After calling setState if I print the name variable to console it still holds old value.
How can I make setState assign a new value to name?
I am aware that setState is asynchronous and update to property may reflect after a delay. But in case of example code above name variable is never updated even after a delay.
I have implemented componentWillReceiveProps(nextProps) method and it gets called but it always receives old name. So I don't think the issue is related to setState being asynchronous.
I have created an example app to demonstrate the issue I am facing. The example app runs fine locally and I can reproduce the issue. But I am not being able to get the same example app code working in codepen. it's giving me some 'unexpected token' errors. But I hope looking at the code will help understand my issue better. The code is based on existing application structure.
Codepen example here.
In the code I have a Parent and two children Child1 and Child2. In Parent I have a function changeState defined which I am passing to Child1 as property. And to Child2 I am passing a 'name' property from Parent.
Clicking on 'Change Name' button in Child1 triggers a call to changeState function of Parent. Initial value of name in Parent is 'Robert'. changeState is invoked from Child1 with new name value of 'Tom'. But in changeState function assigning new value to 'name' using setState has no effect. I am calling a function to print the 'name' after setState has completed but it prints old name value and NOT the new one assigned in setState.
You are using stateless component, there's for, there is no state so the setState function doesn't affect anything.
there are 2 options to deal with it:
the easiest one, but most likely not the best option, just change your component to regular component:
export class Test1 extends React.componnent {
...
(the rest of your component)
}
the second option (usually a better one in my option) is instead of changing the state for the component, get an event from the parent component, and call the event where you wanted to call the setState, the event would contain an updating the value as requested, and the child component would receive it as prop, and your component wouldn't have to change to Container (a component with state)
Good luck!

React JS this.state is undefined: Cannot read property 'components' of undefined, where components is a state of the "Board" Component

I am making a React app in which I play with creating, removing and editing components (more exactly changing their text). I have a basic Component, called 'MyComponent', and a 'Board' component, which contains all the 'MyComponent's created in an array called 'components', which is a state in the 'Board'. Removing and adding a new component works perfectly.
The idea behind editing is that when the user clicks the "Edit" button, the state "Editing" changes to true, and a textarea is displayed so the user can type the new text, and when he wants to click save, the "Editing" state goes back to false, thus going back to the view of a div with the name. (the name should also be updated).
Error name:
Uncaught TypeError: Cannot read property 'components' of undefined.
Link to the code: https://github.com/AndreiEneCristian/ReactComponents/blob/master/EventHandl2.html
For a reason I do not know, whenever I try to save an edited component, thus changing its text and going back to the renderNormal function in "MyComponent", the browser gives me the error "Cannot read property 'components' (which is a state) of undefined". I tried to print some lines in the console, for debugging reasons, the data is correctly handled (meaning the state of 'MyComponent' successfully changes to false, the newText is saved in the "newText" variable) but it crashes because "this.state" is undefined.
The console error points me to this line: "var arr = this.state.components;" in the function:
updateComponent: function(newText, i) {
console.log(this.state);
var arr = this.state.components;
arr[i] = newText;
this.setState({components: arr});
},
Note: this.state is undefined, which is the issue behind it all. How can I solve this?
You have to bind the function you are passing as prop
<MyComponent key={i} index={i} updateComponentText={this.updateComponent.bind(this)} deleteFromBoard={this.removeComponent}>
{text}
</MyComponent>);

Categories

Resources