React中如何通过useEffect Hook依据context值修改checkbox选中状态
实现方案
你想用useEffect监听context.number变化同步更新复选框状态的思路是正确的,只需要新增对应的useEffect逻辑即可,核心要注意模块编号和数组下标的对应关系:模块1对应数组下标0,需要将context.number减1得到要操作的下标。
新增useEffect代码
你可以在handleOnChange方法下方新增以下逻辑:
useEffect(() => { // 模块编号转数组下标 const targetIndex = Number(context.number) - 1 // 下标合法性校验,避免越界报错 if (targetIndex < 0 || targetIndex >= checkedState.length) return const newCheckedState = [...checkedState] // 标识对应模块为已完成,若需求是仅当前模块选中、其余取消,替换为下面注释的代码即可 // const newCheckedState = new Array(modules.length).fill(false) newCheckedState[targetIndex] = true setCheckedState(newCheckedState) // 依赖项添加context.number,保证数值变化时触发更新 }, [context.number, checkedState])
修改后完整代码
import React, { useState, useContext, useEffect } from "react"; import { Link } from "react-router-dom"; import { AppContext } from "../context/AppContext"; export default function Menu() { const context = useContext(AppContext); // 定义模块列表 const modules = [ { title: `Introduction`, subtitle: "Lesson 1", }, { title: `Overview`, subtitle: "Lesson 2", } ]; // 初始化每个模块的选中状态 const [checkedState, setCheckedState] = useState(new Array(modules.length).fill(false)); // 手动切换复选框选中状态的方法 const handleOnChange = (position) => { const updatedCheckedState = checkedState.map((item, index) => index === position ? !item : item ); setCheckedState(updatedCheckedState); }; // 监听context.number变化,自动更新复选框状态 useEffect(() => { const targetIndex = Number(context.number) - 1 if (targetIndex < 0 || targetIndex >= checkedState.length) return const newCheckedState = [...checkedState] // 若需要仅当前模块选中、其余取消,替换为下行代码即可 // const newCheckedState = new Array(modules.length).fill(false) newCheckedState[targetIndex] = true setCheckedState(newCheckedState) }, [context.number, checkedState]) return ( <> <div> {modules.map((module, index) => ( <div className={styles.menuCard} key={index}> <Link to={`/Module/${index + 1}`}> <h2>{module.title}</h2> <p>{module.subtitle}</p> </Link> <input id={`check${index}`} type="checkbox" onChange={() => handleOnChange(index)} checked={checkedState[index]} /> </div> ))} </div> </> ); }
注意事项
- 如果你的需求是所有小于等于
context.number的模块都要标记为已完成,只需要修改useEffect内的赋值逻辑,遍历把所有下标小于等于targetIndex的项都设为true即可。 - 代码中添加了
Number()转换,避免context.number为字符串类型时出现计算错误。
内容的提问来源于stack exchange,提问作者lache
相关产品推荐
相关产品推荐

