Reputation: 803
I have two components <App />
and <CompA/>
The task I want to accomplish is,
I have a state in <App/>
and an input field <CompA/>
and I want to change the state of <App/>
by changing the input in <CompA/>
App.js
export default function App() {
const [containers, setContainers] = useState({
invoiceData: null,
containers: [
{ id: "09d4ba8a-30f1-4bf5-8b9f-ca45c497039a", containerNum: "" }
]
});
const changeContainerNum = (e, index) => {
let current = containers;
current.containers[index].containerNum = e.target.value;
// current variable change on every function call
console.log("local variable", current);
setContainers(current);
};
// but state only change once
console.log("////state", containers);
return (
<div>
{containers.containers.map((container, index) => (
<CompA
key={container.id}
index={index}
changeContainerNum={changeContainerNum}
/>
))}
</div>
);
}
CompA.js
function CompA({ changeContainerNum, index }) {
const [containerNumber, setContainerNumber] = useState("");
return (
<div>
<input
placeholder="Container Number..."
value={containerNumber}
onChange={(e) => {
changeContainerNum(e, index);
setContainerNumber(e.target.value.toUpperCase());
}}
/>
</div>
);
}
export default CompA;
I want to change the containerNum property of containers
state,
The Issue is
when the onChange event gets triggered the changeContainerNum(e, index)
the code works fine in this function but when I assign the new changed value to the state then it updates the state only once
onChange={(e) => {
// 👇
changeContainerNum(e, index);
setContainerNumber(e.target.value.toUpperCase());
}}
How can I update the state on every onChange event. It will be helpful to update code here
Upvotes: 0
Views: 690
Reputation: 18083
You should not mutate a state variable, you must instead create a new reference :
const changeContainerNum = (e, index) => {
const containerNum = e.target.value;
setContainers(({invoiceData, containers})=> ({
invoiceData,
containers: containers.map((container, idx) =>
idx === index ? {...container, containerNum} : container
)
}));
};
Upvotes: 1