切换布尔值并使用useState()更新obj



目前,我有许多复选框,它们显然都与需要在onSubmit上传递的布尔值相关。我最初有这样的东西:

const [value, setValue] = React.useState({
alpha: true,
beta: false,
charlie: false,
// twenty or so more
});
...
<CheckboxComp
aria-label="id"
checked={value.alpha}
onChange={() => setValue({ alpha: !value.alpha})}
label="id"
/>

这让我大吃一惊:

Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. 

然后我发现了这个。

- Through Input
const [state, setState] = useState({ fName: "", lName: "" });
const handleChange = e => {
const { name, value } = e.target;
setState(prevState => ({
...prevState,
[name]: value
}));
};
<input
value={state.fName}
type="text"
onChange={handleChange}
name="fName"
/>
<input
value={state.lName}
type="text"
onChange={handleChange}
name="lName"
/>
***************************
- Through onSubmit or button click

setState(prevState => ({
...prevState,
fName: 'your updated value here'
}));

这几乎和我得到的一样接近,但我在用输入字符串的东西切换真/假时遇到了问题。有什么帮助吗,我知道这是一个愚蠢的问题,但这比继续使用useState(false(x20要好得多,这是离优化最远的东西。

现在我有这样的东西了!

const [value, setValue] = React.useState({
alpha: true,
beta: false,
charlie: false,
});
const handleChange = e => {
const { name, value } = e.target;
setValue(prevState => ({
...prevState,
[name]: value
}));
};
console.log(value)

...
<CheckboxComp
aria-label="id"
checked={value.alpha}
onChange={handleChange}
name="alpha"
label="id"
/>

但console.log显示

alpha: "true"

正如我在评论中指出的,您的setValue调用覆盖了除显式命名的属性之外的所有属性。您展示的向setValue传递回调的示例不仅仅是"针对字符串",它只是一种在维护所有其他属性的同时为单个属性分配新值的方法。请参阅:析构函数赋值和排列语法(…(。

这是一个快速工作的片段。

function App() {
const [value, setValue] = React.useState({
alpha: true,
beta: false,
charlie: false,
// twenty or so more
});
const checkChange = (e) => {
const { id, checked } = e.target;
setValue(prevValue => ({ ...prevValue, [id]: checked }))
};
return (
<div>
<form>
{Object.keys(value).map(k =>
<div key={k}>
<input type="checkbox" id={k} name={k} checked={value[k]} onChange={checkChange} />
<label for={k}>{k}</label>
</div>
)}
</form>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

问题出在Checkbox组件的这段代码中:

onChange={() => setValue({ alpha: !value.alpha})}

当您通过传递{ alpha: !value.alpha }来更新状态时,它实际上是在修改对象时从对象中删除所有其他键,而不是修改键的特定值,同时保持所有其他键相同

您应该使用排列运算符或Object.assign来提供修改后的新对象。

对于您当前的代码,当setValue被激发时,您的状态对象留下{ alpha: false },而它应该是{ alpha: false, beta: false, ...}

最新更新