[英]How change value of checkbox checked using useState in React
我会将带有属性的复选框字段列表传递给我的组件,我想根据人的选择来更改checked
属性的值,但我能做的最多是将数组中的检查值加倍。
如何在我的 state 中更改此特定密钥?
这是我的代码:
export default function Combocheck({ data, title, id }) {
const inputLabel = React.useRef(null);
const [state, setState] = React.useState({
checkbox: data.map((element) => {
element.checked = false;
return element;
})
});
const changeState = name => event => {
const newValue = !state.checkbox[name].checked;
setState({ checkbox: [
...state.checkbox,
state.checkbox[name] = {
...state.checkbox[name],
checked: newValue
}
]
});
}
console.log(state);
return (
<div>
<Typography color='textSecondary'>{title}</Typography>
<Divider />
<FormGroup>
{state.checkbox.map(({code, description, checked}, i) => {
return <FormControlLabel control={
<Checkbox
key={code}
checked={checked}
onChange={changeState(i)}
value={code}
color="primary"
/>
}
key={code}
label={description}
/>
})}
</FormGroup>
</div>
);
}
可以在这里查看或编辑: https://stackblitz.com/edit/react-irhqw9?file=Hello.js
每次更新 state 时,您都会添加一个复选框项目,而是:考虑映射您的元素并仅更改适用的元素:
const changeState = name => event => {
setState({
checkbox: state.checkbox.map((checkbox, i) => {
return i !== name ?
checkbox :
{ ...checkbox, checked: !checkbox.checked }
})
});
}
我也不喜欢使用元素索引作为名称。 我很确定你会很好地使用代码(假设它是唯一的),然后这不需要是更高阶的 function:
const changeState = event => {
setState({
checkbox: state.checkbox.map((checkbox) => {
return event.target.value !== checkbox.code ?
checkbox :
{ ...checkbox, checked: !checkbox.checked }
})
});
}
然后在Checkbox
道具中:
onChange={changeState}
我更喜欢为每个复选框使用一个 useState function。
In the 'old days' before hooks, each component had only one state - and the setState
function would merge that state with the object passed to setState
. Hooks & useState 不会那样做。 您可以在一个组件中拥有多个 useState 挂钩,并且 state 不会合并。
这里有一些代码可以粘贴到使用 create-react-app 创建的 App.js 中来说明我的意思:
应用程序.js
import React, { useState } from 'react';
function App() {
var [ firstCheckbox, setFirstCheckbox ] = useState(true); // true - first check box defaults to checked.
var [ secondCheckbox, setSecondCheckbox ] = useState(false); // false = second check box defaults to un-checked.
return (
<div style={{display:'flex', flexDirection: 'column'}}>
<label for='first-check-box'><input type="checkbox" checked={firstCheckbox} onChange={() => setFirstCheckbox(!firstCheckbox)}></input>First Check Box</label>
<label for='second-check-box'><input type="checkbox" checked={secondCheckbox} onChange={() => setSecondCheckbox(!secondCheckbox)}></input>Second Check Box</label>
</div>
);
}
export default App;
另一个使 chrome 开发者工具更有用的提示:当你按照我的建议使用许多 useState 钩子时,很难看出哪个 state 钩子是哪个。 每个 useState 挂钩只显示为useState: true
,没有任何标签。 以下代码通过使实际 state 成为 object 的属性来标识开发人员工具的“组件”选项卡中的 useState 挂钩,其中键是 label 以显示在 chrome 开发人员工具中。
应用程序.js:
import React, { useState } from 'react';
function App() {
var [ firstCheckbox, setFirstCheckbox ] = useState({firstCheckBox: true});
var [ secondCheckbox, setSecondCheckbox ] = useState({secondCheckBox: false});
return (
<div style={{display:'flex', flexDirection: 'column'}}>
<label htmlFor='first-check-box'>
<input type="checkbox"
checked={firstCheckbox.firstCheckBox}
onChange={() => setFirstCheckbox(
{firstCheckBox: !firstCheckbox.firstCheckBox}
)}>
</input>
First Check Box
</label>
<label htmlFor='second-check-box'>
<input
type="checkbox"
checked={secondCheckbox.secondCheckBox}
onChange={() => setSecondCheckbox(
{secondCheckBox: !secondCheckbox.secondCheckBox}
)}>
</input>
Second Check Box
</label>
</div>
);
}
export default App;
上面,为了清楚起见,我使用了输入元素的 onChange() 事件。 这需要用户点击实际的复选框。 我更愿意让他们点击 label 或复选框上的任意位置。 为此,我们可以使用 label 元素的 onClick 事件:
为了防止在控制台中抱怨输入不是 controller,我也将它们标记为只读。
应用程序.js:
import React, { useState } from 'react';
function App() {
var [ firstCheckbox, setFirstCheckbox ] = useState({firstCheckBox: true});
var [ secondCheckbox, setSecondCheckbox ] = useState({secondCheckBox: false});
return (
<div style={{display:'flex', flexDirection: 'column'}}>
<label
htmlFor='first-check-box'
onClick={() => setFirstCheckbox({firstCheckBox: !firstCheckbox.firstCheckBox})}>
<input type="checkbox" checked={firstCheckbox.firstCheckBox} readOnly/>
First Check Box
</label>
<label
htmlFor='second-check-box'
onClick={() => setSecondCheckbox({secondCheckBox: !secondCheckbox.secondCheckBox})}>
<input type="checkbox" checked={secondCheckbox.secondCheckBox} readOnly/>
Second Check Box
</label>
</div>
);
}
export default App;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.