admin管理员组文章数量:1302418
I will pass a list of checkbox fields with attributes to my ponent, I would like to change the value of checked
attribute as the person selects or not, but the most I could do was double the check value in array.
How can I change this specific key in my state?
This is my code:
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>
);
}
Can be see or edit here: .js
I will pass a list of checkbox fields with attributes to my ponent, I would like to change the value of checked
attribute as the person selects or not, but the most I could do was double the check value in array.
How can I change this specific key in my state?
This is my code:
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>
);
}
Can be see or edit here: https://stackblitz./edit/react-irhqw9?file=Hello.js
Share Improve this question asked Oct 23, 2019 at 22:48 MarceloBoniMarceloBoni 2411 gold badge7 silver badges16 bronze badges2 Answers
Reset to default 5You're adding a checkbox item each time you update your state! Instead, consider mapping over your elements and only changing the one that's applicable:
const changeState = name => event => {
setState({
checkbox: state.checkbox.map((checkbox, i) => {
return i !== name ?
checkbox :
{ ...checkbox, checked: !checkbox.checked }
})
});
}
I'm also not a huge fan of using the element index as the name; I'm pretty sure you'll be just fine using the code (assuming it's unique), and then this doesn't need to be a higher order function:
const changeState = event => {
setState({
checkbox: state.checkbox.map((checkbox) => {
return event.target.value !== checkbox.code ?
checkbox :
{ ...checkbox, checked: !checkbox.checked }
})
});
}
and then in the Checkbox
props:
onChange={changeState}
I prefer to use one useState function for each checkbox.
In the 'old days' before hooks, each ponent had only one state - and the setState
function would merge that state with the object passed to setState
. Hooks & useState does not do it that way. You can have many useState hooks in one ponent, and the state does not merge.
Here is some code you can paste into App.js created using create-react-app to show what I mean:
App.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;
Another hint for make the chrome developer tools more useful:
When you use many useState hooks as I suggest, it can be hard to see which state hook is which. Each of the useState hooks just shows as useState: true
without any labels. The following code identifies the useState hook in the Components tab of the developer tools by making the actual state a property of an object, with the key being a label to show in the chrome developer tools.
App.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;
Above, I used the input element's onChange() event for clarity. This requires the user to click on the actual check box. I prefer to allow them to click anywhere on the label OR the checkbox. To do this we can use the label element's onClick event:
To prevent react plaining in the console about the inputs not being controller, I mark them as readOnly also.
App.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;
本文标签: javascriptHow change value of checkbox checked using useState in ReactStack Overflow
版权声明:本文标题:javascript - How change value of checkbox checked using useState in React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741649858a2390407.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论