I'm trying to change the state of a component but it keep rendering the previous state.
From what I understood, the component is rendered before the state is getting saved and I need to use a callback function, except that I did not succeed.
Here is a simplified code of what I'm trying to do:
export default function ColorPick() {
const [color, setColor] = useState('');
const [choice, setChoice] = useState('blue');
const handleColor = (event, newChoice) => {
setChoice(newChoice)
if(choice === 'blue'){
setColor('blue')
}else{
setColor('red')
}
};
return (
<select onChange={handleColor} value={choice}>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
<h1>{color}</h1>
);
}
Thank you
CodePudding user response:
You can just use the event parameter which returns the selected value. Then your handleColor will look like this
const handleColor = (event) => {
console.log(event.target.value);
if (event.target.value === "blue") {
setColor("blue");
} else {
setColor("red");
}
};
<select onChange={handleColor}>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
<h1>{color}</h1>
Then also you don't need to use the choice state
Codesandbox example
CodePudding user response:
when you assign an onChange method like this, the component (<select>) only sends event argument to it. If you debug your handleColor method, you will see that the newChoice argument is always undefined.
You can access select's current value with event.target.value and you can even get rid of the choice hook altogether.
function ColorPick() {
const [color, setColor] = useState("")
const handleColor = (event) => {
setColor(event.target.value)
}
return (
<>
<select onChange={handleColor}>
<option value='red'>Red</option>
<option value='blue'>Blue</option>
</select>
<h1>{color}</h1>
</>
)
}
CodePudding user response:
useState is asynchrnous so you can't access new choice value in handleColor function, in addition yan can't access newChoice in your function as you don't pass any parameter, your handleColor function only receive event as a callback parameter. In your case you could get rid of choice and setChoice like this
const {useState} = React
function ColorPick() {
const [color, setColor] = useState('blue');
const handleColor = (event) => {
setColor(event.target.value)
};
return (
<>
<select onChange={handleColor} value={color}>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
<h1>{color}</h1>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<>
<ColorPick />
</>
);
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script
crossorigin
src="https://unpkg.com/react@18/umd/react.production.min.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
></script>
<div id="root"></div>
