Change React React Child Component在父母的onclick事件中的状态,带有回调和钩子(USESTATE,useFeft)
我的父组件包含一系列类别。该组件呈现一个列表,每个列表项目都有一个复选框,这是子组件。
我将usestate()用于checkedcategory数组,以及子组件复选框的检查/未检查状态。
- 如果我检查复选框,则将类别添加到列表中。复选框儿童组件的状态(已检查)在子组件(复选框.js)中更新,
- 如果我取消选中复选框,则该类别将从列表中删除。复选框儿童组件的状态(已检查)在子组件(checkbox.js)中进行了更新。
- 我有一个“清除所有”按钮,可更新父母的检查效率状态。
- 每次更新checkedCategory数组时,我都会触发使用使用效果钩的控制台。log,这适用于所有三种情况。
还有一个细节:当单击“清除所有”按钮时,所有复选框都应不选中。因此,我必须以某种方式操纵所有复选框儿童的检查状态。
父元组件:
import {useState, useEffect} from "react";
import Checkbox from "../functions/Checkbox.js";
function CategoryList() {
const categories = ['CategoryA','CategoryB', 'CategoryC']
const [checkedCategories, setCheckedCategories] = useState([]);
const addToCheckedCategories = id => {
const updatedCheckedCategories = [...checkedCategories];
updatedCheckedCategories.push(id);
setCheckedCategories(updatedCheckedCategories);
};
const removeFromCheckedCategories = id => {
const updatedCheckedCategories = checkedCategories.filter(cat => cat !== id);
setCheckedCategories(updatedCheckedCategories);
};
const removeFilters = () => {
//????
}
useEffect(() => {
console.log('checked categories updated');
console.log(checkedCategories);
if (!checkedCategories.length) {
console.log('the array is empty');
//Set all the checkboxes' checked state to "false" somehow...?
}
}, [checkedCategories]);
return(
<div>
<ul>
{categories.map(categories =>
<li key={categories.toLowerCase()}>
<Checkbox id={categories.toLowerCase()}
label={categories}
addToCheckedCategories={addToCheckedCategories}
removeFromCheckedCategories={removeFromCheckedCategories}
/>
</li>
)}
</ul>
<button onClick={removeFilters}>Clear all</button>
</div>
)
}
export default CategoryList;
儿童组件:
import { useState } from 'react';
function Checkbox({id, label, addToCheckedCategories, removeFromCheckedCategories}) {
const [checked, setChecked] = useState(false);
const handleChange = id => {
if (checked) {
removeFromCheckedCategories(id);
console.log('removed ' + id);
} else {
addToCheckedCategories(id);
console.log('added ' + id);
}
setChecked(!checked);
console.log('changed value of checkbox');
}
return(
<label htmlFor={id} >
<input type="checkbox"
name="category-input"
id={id}
onChange={handleChange}
/>
{label}
</label>
);
}
export default Checkbox;
My parent component contains an array of categories. The component renders a list, and each list item has a checkbox, which is a child component.
I use useState() for the checkedCategories array, and for the checked/unchecked state of the the child component Checkbox.
- If I check a checkbox, the category is added to the list. The checkbox child component's state (checked) is updated in the child component (Checkbox.js)
- If I uncheck a checkbox, the category is removed from the list. The checkbox child component's state (checked) is updated in the child component (Checkbox.js).
- I have a "clear all" button that updates the parent's checkedCategories state.
- Every time the checkedCategories array is updated, I trigger a console.log with the useEffect hook, and this works for all three cases.
There is one detail left: when the "clear all" button is clicked, all the checkboxes should be unchecked. So I have to manipulate the checked state of all the Checkbox children somehow.
Parent component:
import {useState, useEffect} from "react";
import Checkbox from "../functions/Checkbox.js";
function CategoryList() {
const categories = ['CategoryA','CategoryB', 'CategoryC']
const [checkedCategories, setCheckedCategories] = useState([]);
const addToCheckedCategories = id => {
const updatedCheckedCategories = [...checkedCategories];
updatedCheckedCategories.push(id);
setCheckedCategories(updatedCheckedCategories);
};
const removeFromCheckedCategories = id => {
const updatedCheckedCategories = checkedCategories.filter(cat => cat !== id);
setCheckedCategories(updatedCheckedCategories);
};
const removeFilters = () => {
//????
}
useEffect(() => {
console.log('checked categories updated');
console.log(checkedCategories);
if (!checkedCategories.length) {
console.log('the array is empty');
//Set all the checkboxes' checked state to "false" somehow...?
}
}, [checkedCategories]);
return(
<div>
<ul>
{categories.map(categories =>
<li key={categories.toLowerCase()}>
<Checkbox id={categories.toLowerCase()}
label={categories}
addToCheckedCategories={addToCheckedCategories}
removeFromCheckedCategories={removeFromCheckedCategories}
/>
</li>
)}
</ul>
<button onClick={removeFilters}>Clear all</button>
</div>
)
}
export default CategoryList;
Child component:
import { useState } from 'react';
function Checkbox({id, label, addToCheckedCategories, removeFromCheckedCategories}) {
const [checked, setChecked] = useState(false);
const handleChange = id => {
if (checked) {
removeFromCheckedCategories(id);
console.log('removed ' + id);
} else {
addToCheckedCategories(id);
console.log('added ' + id);
}
setChecked(!checked);
console.log('changed value of checkbox');
}
return(
<label htmlFor={id} >
<input type="checkbox"
name="category-input"
id={id}
onChange={handleChange}
/>
{label}
</label>
);
}
export default Checkbox;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将完全提高状态到父母,制作
复选框
组件无状态:从您的父级,您可以将
检查
属性传递,只需检查该类别是否存在于checkedCategories 数组。
使用这种方法清除全部非常容易,您要做的就是将
checkedCategories
数组设置为空一个。演示: https://stackblitz.com/edit/eedit/react-pwxgaq qy? file = src%2fapp.js
I would lift the state completely to the parent making the
Checkbox
component stateless:From your parent you can pass down the
checked
property simply checking if that category is present in thecheckedCategories
array.Using this approach clearing all is very easy, all you have to do is setting the
checkedCategories
array to an empty one.Demo: https://stackblitz.com/edit/react-pwxgaq?file=src%2FApp.js