无法通过 React 以编程方式重置复选框 Bootstrap
Having trouble getting checkboxes to programmatically reset with React Bootstrap
我找到了以编程方式重置复选框列表中的选项的解决方案,但是,由于某种原因,图形元素本身不会更改以匹配状态。我以为它会在状态更改时自动执行它,但是,除了我目前正在做的事情之外,似乎还必须有一种我应该单独执行它的方法。
首先,我初始化复选框选项:
const [categoryFilterOptions, setCategoryFilterOptions] = useState([{label: 'Category1', checked: true}, {label: 'Category2', checked: true}, {label: 'Category3', checked: true}, {label: 'Category4', checked: true}])
这会在渲染时传递到我的清单组件并像这样处理:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
defaultChecked={checkItem.checked}
onClick={() => {setCheck(i)}}
></Form.Check>
)) }
然后要重置它们,我有一个按钮:
<Button style={{width: '100%'}} onClick={() => {resetAllChecks()}}>Reset Filter</Button>
调用方法 resetAllChecks() 将我的检查选项设置回初始状态:
const resetAllChecks = () => {
setFamilyFilterOptions([{label: 'String', checked: true}, {label: 'Percussion', checked: true}, {label: 'Brass', checked: true}, {label: 'Wind', checked: true}, {label: 'Electronic', checked: true}, {label: 'Keyboard', checked: true}])
setCategoryFilterOptions([{label: 'Contemporary', checked: true}, {label: 'Orchestral', checked: true}, {label: 'Traditional', checked: true}, {label: 'Vocal', checked: true}])
}
我真的不确定为什么它拒绝重置复选框的图形元素,因为列表被重置得很好,但复选框却没有。
编辑:
下面是一些周边的代码,可能上下文比较好?
从编程上讲,它在数据方面工作得很好,只是图形没有更新,所以我不确定这是否会有很大帮助,但值得一试!
const DropdownChecklist = ({disabled, checkOptions, returnChecksState}) => {
const [checks, setChecks] = useState([...checkOptions]);
function setCheck(id){
var newArray = [...checks]
var newElement = checks[id];
newElement.checked = (!newElement.checked)
newArray[id] = newElement;
setChecks(newArray);
returnChecksState(checks);
}
console.log(checks)
return (
<Form className={styles.checkMenu}>
<fieldset disabled={disabled}>
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
</fieldset>
</Form>
)
}
export default DropdownChecklist
编辑 2:更多上下文
<Col>
<h5 style={{textAlign: 'center', color: 'white'}}>Category Filtering: </h5>
<DropdownChecklist disabled={false} checkOptions={categoryFilterOptions} returnChecksState={setCategoryFilterOptions}></DropdownChecklist>
</Col>
编辑 3:
我尝试使用提供的解决方案 Here,但它仍然无法正常工作,但是,我现在意识到,不知何故,我正在重置我的检查的组件逻辑以某种方式直接触及我的 DEFAULT_CHECKS 值,这是没有意义的对我来说,特别是因为它是一个 const 值,甚至不应该改变
defaultChecked
属性只能与 uncontrolled components 一起使用,在大多数情况下您不需要。您看到的行为是预期的:
Changing the value of defaultValue attribute after a component has
mounted will not cause any update of the value in the DOM.
当您想要以编程方式操作您的输入值时,您通常应该更喜欢 controlled components。这个想法是输入应该总是从 React 的状态中获取它的值,并且与输入的交互应该相应地更新状态。
对于复选框,这意味着设置 checked
和 onChange
道具,所以它看起来像:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
现在,当您调用 resetAllChecks()
时,复选框应该 re-render 具有状态中的最新值。
您不应尝试同时更改父状态和子状态。让父级处理更改并将它们传递给新道具。
import React, { useState } from 'react';
import { Col, Form, Button } from 'react-bootstrap';
export default function App() {
const [categoryFilterOptions, setCategoryFilterOptions] = useState([
{ label: 'Category1', checked: true },
{ label: 'Category2', checked: true },
{ label: 'Category3', checked: true },
{ label: 'Category4', checked: true },
]);
const resetAllChecks = () => {
setCategoryFilterOptions(
categoryFilterOptions.map((option) => ({
label: option.label,
checked: true,
}))
);
};
return (
<Col>
<h5 style={{ textAlign: 'center', color: 'black' }}>
Category Filtering:
</h5>
<DropdownChecklist
disabled={false}
checkOptions={categoryFilterOptions}
returnChecksState={setCategoryFilterOptions}
></DropdownChecklist>
<Button
style={{ width: '100%' }}
onClick={() => {
resetAllChecks();
}}
>
Reset Filter
</Button>
</Col>
);
}
const DropdownChecklist = ({ disabled, checkOptions, returnChecksState }) => {
function setCheck(id) {
var newArray = [...checkOptions];
var newElement = checkOptions[id];
newElement.checked = !newElement.checked;
newArray[id] = newElement;
returnChecksState(newArray);
}
return (
<Form>
<fieldset disabled={disabled}>
{checkOptions.map((checkItem, i) => (
<Form.Check
key={checkItem.label}
id={i}
type="checkbox"
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {
setCheck(i);
}}
></Form.Check>
))}
</fieldset>
</Form>
);
};
你可以看到一个工作示例here
先生,不要使用不受控制的组件。
我找到了以编程方式重置复选框列表中的选项的解决方案,但是,由于某种原因,图形元素本身不会更改以匹配状态。我以为它会在状态更改时自动执行它,但是,除了我目前正在做的事情之外,似乎还必须有一种我应该单独执行它的方法。
首先,我初始化复选框选项:
const [categoryFilterOptions, setCategoryFilterOptions] = useState([{label: 'Category1', checked: true}, {label: 'Category2', checked: true}, {label: 'Category3', checked: true}, {label: 'Category4', checked: true}])
这会在渲染时传递到我的清单组件并像这样处理:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
defaultChecked={checkItem.checked}
onClick={() => {setCheck(i)}}
></Form.Check>
)) }
然后要重置它们,我有一个按钮:
<Button style={{width: '100%'}} onClick={() => {resetAllChecks()}}>Reset Filter</Button>
调用方法 resetAllChecks() 将我的检查选项设置回初始状态:
const resetAllChecks = () => {
setFamilyFilterOptions([{label: 'String', checked: true}, {label: 'Percussion', checked: true}, {label: 'Brass', checked: true}, {label: 'Wind', checked: true}, {label: 'Electronic', checked: true}, {label: 'Keyboard', checked: true}])
setCategoryFilterOptions([{label: 'Contemporary', checked: true}, {label: 'Orchestral', checked: true}, {label: 'Traditional', checked: true}, {label: 'Vocal', checked: true}])
}
我真的不确定为什么它拒绝重置复选框的图形元素,因为列表被重置得很好,但复选框却没有。
编辑: 下面是一些周边的代码,可能上下文比较好?
从编程上讲,它在数据方面工作得很好,只是图形没有更新,所以我不确定这是否会有很大帮助,但值得一试!
const DropdownChecklist = ({disabled, checkOptions, returnChecksState}) => {
const [checks, setChecks] = useState([...checkOptions]);
function setCheck(id){
var newArray = [...checks]
var newElement = checks[id];
newElement.checked = (!newElement.checked)
newArray[id] = newElement;
setChecks(newArray);
returnChecksState(checks);
}
console.log(checks)
return (
<Form className={styles.checkMenu}>
<fieldset disabled={disabled}>
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
</fieldset>
</Form>
)
}
export default DropdownChecklist
编辑 2:更多上下文
<Col>
<h5 style={{textAlign: 'center', color: 'white'}}>Category Filtering: </h5>
<DropdownChecklist disabled={false} checkOptions={categoryFilterOptions} returnChecksState={setCategoryFilterOptions}></DropdownChecklist>
</Col>
编辑 3: 我尝试使用提供的解决方案 Here,但它仍然无法正常工作,但是,我现在意识到,不知何故,我正在重置我的检查的组件逻辑以某种方式直接触及我的 DEFAULT_CHECKS 值,这是没有意义的对我来说,特别是因为它是一个 const 值,甚至不应该改变
defaultChecked
属性只能与 uncontrolled components 一起使用,在大多数情况下您不需要。您看到的行为是预期的:
Changing the value of defaultValue attribute after a component has mounted will not cause any update of the value in the DOM.
当您想要以编程方式操作您的输入值时,您通常应该更喜欢 controlled components。这个想法是输入应该总是从 React 的状态中获取它的值,并且与输入的交互应该相应地更新状态。
对于复选框,这意味着设置 checked
和 onChange
道具,所以它看起来像:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
现在,当您调用 resetAllChecks()
时,复选框应该 re-render 具有状态中的最新值。
您不应尝试同时更改父状态和子状态。让父级处理更改并将它们传递给新道具。
import React, { useState } from 'react';
import { Col, Form, Button } from 'react-bootstrap';
export default function App() {
const [categoryFilterOptions, setCategoryFilterOptions] = useState([
{ label: 'Category1', checked: true },
{ label: 'Category2', checked: true },
{ label: 'Category3', checked: true },
{ label: 'Category4', checked: true },
]);
const resetAllChecks = () => {
setCategoryFilterOptions(
categoryFilterOptions.map((option) => ({
label: option.label,
checked: true,
}))
);
};
return (
<Col>
<h5 style={{ textAlign: 'center', color: 'black' }}>
Category Filtering:
</h5>
<DropdownChecklist
disabled={false}
checkOptions={categoryFilterOptions}
returnChecksState={setCategoryFilterOptions}
></DropdownChecklist>
<Button
style={{ width: '100%' }}
onClick={() => {
resetAllChecks();
}}
>
Reset Filter
</Button>
</Col>
);
}
const DropdownChecklist = ({ disabled, checkOptions, returnChecksState }) => {
function setCheck(id) {
var newArray = [...checkOptions];
var newElement = checkOptions[id];
newElement.checked = !newElement.checked;
newArray[id] = newElement;
returnChecksState(newArray);
}
return (
<Form>
<fieldset disabled={disabled}>
{checkOptions.map((checkItem, i) => (
<Form.Check
key={checkItem.label}
id={i}
type="checkbox"
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {
setCheck(i);
}}
></Form.Check>
))}
</fieldset>
</Form>
);
};
你可以看到一个工作示例here
先生,不要使用不受控制的组件。