gpt4 book ai didi

ReactJS:使用 useState 管理多个复选框输入

转载 作者:行者123 更新时间:2023-12-03 23:08:42 25 4
gpt4 key购买 nike

我有以下示例组件,它使用多个复选框来选择要从对象列表中删除的项目:

import React, { useState } from "react";
import "./styles.css";

const data = [
{
name: "test1",
result: "pass"
},
{
name: "test2",
result: "pass"
},
{
name: "test3",
result: "pass"
},
{
name: "test4",
result: "pass"
},
{
name: "test5",
result: "pass"
}
];

export default function App() {
const [allChecked, setAllChecked] = useState(false);
const [isChecked, setIsChecked] = useState({});
const [formData, setFormData] = useState(data);

const handleAllCheck = e => {
setAllChecked(e.target.checked);
};

const handleSingleCheck = e => {
setIsChecked({ ...isChecked, [e.target.name]: e.target.checked });
};

const onDelete = () => {
console.log(isChecked);
const newData = data.filter(
item => !Object.keys(isChecked).includes(item.name)
);
console.log(newData);
setFormData(newData);
};

return (
<div className="App">
<div>
<label>All</label>
<input
name="checkall"
type="checkbox"
checked={allChecked}
onChange={handleAllCheck}
/>
<label />
</div>
{formData.map((test, index) => (
<div key={index}>
<label>{test.name}</label>
<input
type="checkbox"
name={test.name}
checked={allChecked ? true : isChecked[test.name]}
onChange={handleSingleCheck}
/>
</div>
))}
<button onClick={() => onDelete()}>DELETE</button>
</div>
);
}

这主要是工作,除了检查所有。似乎 onChange 在使用 useState 时不会更新。我需要能够选择所有对象或取消选中某些对象以标记为删除。

非常感谢任何帮助。

代码沙盒示例:https://codesandbox.io/s/modest-hodgkin-kryco

更新:

好的,在 Richard Matsen 的帮助下,

这是一个没有直接 DOM 操作的新解决方案:

import React, { useState, useEffect } from "react";
import "./styles.css";

const data = [
{
name: "test1",
result: "pass"
},
{
name: "test2",
result: "pass"
},
{
name: "test3",
result: "pass"
},
{
name: "test4",
result: "pass"
},
{
name: "test5",
result: "pass"
}
];

export default function App() {
const [allChecked, setAllChecked] = useState(false);
const [isChecked, setIsChecked] = useState();
const [loading, setLoading] = useState(true);
const [formData, setFormData] = useState(data);

const handleAllCheck = e => {
setAllChecked(e.target.checked);
};

const handleSingleCheck = e => {
setIsChecked({ ...isChecked, [e.target.name]: e.target.checked });
};

const onDelete = () => {
const itemList = Object.keys(isChecked).map((key:any) => {
if (isChecked[key] === true) {
return key
}
})
const result = formData.filter((item:any) => !itemList.includes(item.name))
console.log(result)
setFormData(result)
}

useEffect(() => {
if (!loading) {
setIsChecked(current => {
const nextIsChecked = {}
Object.keys(current).forEach(key => {
nextIsChecked[key] = allChecked;
})
return nextIsChecked;
});
}
}, [allChecked, loading]);

useEffect(() => {
const initialIsChecked = data.reduce((acc,d) => {
acc[d.name] = false;
return acc;
}, {})
setIsChecked(initialIsChecked)
setLoading(false)
}, [loading])

return (
<div className="App">
<div>
<label>All</label>
<input
name="checkall"
type="checkbox"
checked={allChecked}
onChange={handleAllCheck}
/>
<label />
</div>
{!loading ? formData.map((test, index) => (
<div key={index}>
<label>{test.name}</label>
<input
type="checkbox"
name={test.name}
checked={isChecked[test.name]}
onChange={handleSingleCheck}
/>
</div>
)): null}
<button onClick={() => onDelete()}>DELETE</button>
</div>
);
}

工作解决方案的codesandbox: https://codesandbox.io/s/happy-rubin-5zfv3

最佳答案

基本问题是 checked={allChecked ? true : isChecked[test.name]} 停止取消检查操作的发生 - 一旦 allChecked 为真,什么值都没有关系 isChecked[test.name]有,表达总是会是真实的。

您应该仅依赖于 isChecked 的值,并将更改 allChecked 视为副作用。

  useEffect(() => {
setIsChecked(current => {
const nextIsChecked = {}
Object.keys(current).forEach(key => {
nextIsChecked[key] = allChecked;
})
return nextIsChecked;
});
}, [allChecked]);

...

{formData.map((test, index) => (
<div key={index}>
<label>{test.name}</label>
<input
type="checkbox"
name={test.name}
checked={isChecked[test.name]}
onChange={handleSingleCheck}
/>
</div>
))}

还有这个警告突然出现

Warning: A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

所以这基本上就是说不要将 isChecked 初始化为 {},因为输入的 checked 属性最初是未定义的。改用这个,

{
test1: false,
test2: false,
test3: false,
test4: false,
test5: false,
}

或者这样

const data = { ... }

const initialIsChecked = data.reduce((acc,d) => {
acc[d.name] = false;
return acc;
}, {})

export default function App() {
const [allChecked, setAllChecked] = useState(false);
const [isChecked, setIsChecked] = useState(initialIsChecked);
...

关于ReactJS:使用 useState 管理多个复选框输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60456547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com