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>