I have the following react compoment:
const WifiBasic = () => {
const [wifiinfo, setWifiinfo] = useState({});
const setSsid = (value) => {
let info = wifiinfo;
info.ssid = value;
setWifiinfo(info);
}
return (
<>
<input type="text" className="mt-1 block w-full" onChange={(e)=> setSsid(e.target.value)} value={wifiinfo && wifiinfo.ssid} />
</>
);
I cant't type in text filed, nothing changed in input ui. I try to fix this after some search, it worked.
const WifiBasic = () => {
const [wifiinfo, setWifiinfo] = useState({});
const setSsid = (value) => {
setWifiinfo({...wifiinfo, ssid: value});
}
return (
<>
<input type="text" className="mt-1 block w-full" onChange={(e)=> setSsid(e.target.value)} value={wifiinfo && wifiinfo.ssid} />
</>
);
What's the problem caused this problem? Is there any document about data update?
CodePudding user response:
In the first example, every time you type you set the state of the component, causing it to re-render, so when you type the input clears every time.
The second time you stored the input value in state so every time the component re-renders you set the value of the input.
CodePudding user response:
The reason the component is not rendering after the change is because of how Object comparisms is done in javascript, comparisms of objects are done by reference not the content of the object For Example
const a = {name: 'House Map'}
// comparing a to itself is true
console.log(a === a) // This line returns true
const b = a;
console.log(a === b) // this line returns true because they both point to the same reference
// =========================NOW CONSIDER THIS EXAMPLE=========================================
const c = {name: 'John'};
const d = {name: 'John'};
console.log(c === d) // This will return false because they point to different object even though their content is the same
// NOW CONSIDER THIS
const e = {...c,address: "working road"}; // object destructing gives new object and copy properties and values of c
const h = Object.assign({},c); // same as step above but using global Object to do the copying
h.address = 'working address'
const f = c;
f.address = 'working address'
console.log(e === c ) // false
console.log(f === c ) // true
console.log(f === h ) // false
For react to rerender the previous state must not be equal to the present state and since you are using object on the state the above shows that we have to return a new object that is why the state is not reRendering
CodePudding user response:
This is a case of reference issue.
const setSsid = (value) => {
let info = wifiinfo;
info.ssid = value;
setWifiinfo(info);
}
let info = wifiinfo
By doing this you are instead making a reference to the wifiinfo, which being a state in react, isn't allowed mutation.
If you just change let info = wifiinfo to let info = {...wifiinfo}. You'll see it behaves normally. Reason being now you are making a new copy of the object and mutating that which is valid in React.
