When I am using textarea or input text field in reactjs, and state is set with direct variable it works fine. If state is set through object it does not work. To explain it better I am writing code below for both the cases.
Case 1 (works fine)
const [description, setDescription] = useState('');
<label>Test suite description</label>
<textarea value={description} name="description"
rows={4} cols={5} style={{width: "100%"}}
onChange={(e) => setDescription(e.target.value)}>
</textarea>
Case 2 (does not work)
const [tsData, setTsData] = useState({
tsname: "",
description: "",
plugin: 100,
type: 900,
freq: 100,
report: 0,
});
const handleTextAreaType=(value)=> {
const newTsData = tsData;
newTsData.description = value;
setTsData(newTsData);
}
<label>Test suite description</label>
<textarea value={description} name="description"
rows={4} cols={5} style={{width: "100%"}}
onChange={(e) => handleTextAreaType(e.target.value)}>
</textarea>
While Case 1 code works fine and Case 2 code does not work. What is the reason why case 2 code does not work?
>Solution :
In react, you can’t directly mutate the state. Instead you need to create a new object everytime.
So instead of doing const newTsData = tsData;, do this const newTsData = {...tsData};
This will create a new object with a different reference, and hence react will know that state has changed and it will then re-render. If you directly copy the state to a new variable, the reference is still the same (since it is an object) and hence react would think that state is still the same and hence it would not re-render
const [tsData, setTsData] = useState({
tsname: "",
description: "",
plugin: 100,
type: 900,
freq: 100,
report: 0,
});
const handleTextAreaType=(value)=> {
const newTsData = {...tsData};
newTsData.description = value;
setTsData(newTsData);
}
<label>Test suite description</label>
<textarea value={description} name="description"
rows={4} cols={5} style={{width: "100%"}}
onChange={(e) => handleTextAreaType(e.target.value)}>
</textarea>