为何绑定含useState的父组件函数时复选框失效?如何修复?
解决复选框因父组件状态更新导致的功能异常问题
问题原因
当调用setArr更新父组件App的状态时,App会触发重新渲染。由于Row组件是定义在App内部的函数组件,每次App渲染都会重新创建一个全新的Row组件类型。React会将其识别为不同的组件,进而卸载旧的Row实例并挂载新的,导致复选框的状态被重置,表现为功能异常。
解决方案
方案1:将Row组件移到App组件外部
把Row组件从App内部提取出来,确保App重新渲染时Row的组件类型保持稳定,不会触发卸载重建:
import { useState, useEffect } from "react"; import "./styles.css"; // 移到App组件外部 const Row = ({ index, onCheckboxChange }) => { const [checked, setChecked] = useState(false); return ( <> <input name="mychecky" type="checkbox" checked={checked} onChange={(e) => { setChecked(e.target.checked); onCheckboxChange(index); }} /> <label htmlFor="mychecky">My checkbox</label> </> ); }; export default function App() { const [arr, setArr] = useState([]); useEffect(() => { console.log(arr); }, [arr]); function outerFunction(index) { console.log(index); setArr([index]); } return ( <div className="App"> <Row index={3} onCheckboxChange={outerFunction} /> </div> ); }
方案2:使用useMemo缓存Row组件
如果必须将Row留在App内部,可以用useMemo缓存组件,确保每次App渲染时Row的引用不变:
import { useState, useEffect, useMemo } from "react"; import "./styles.css"; export default function App() { const [arr, setArr] = useState([]); useEffect(() => { console.log(arr); }, [arr]); function outerFunction(index) { console.log(index); setArr([index]); } // 用useMemo缓存Row组件,依赖项为空数组保证引用稳定 const Row = useMemo(() => { return ({ index }) => { const [checked, setChecked] = useState(false); return ( <> <input name="mychecky" type="checkbox" checked={checked} onChange={(e) => { setChecked(e.target.checked); outerFunction(index); }} /> <label htmlFor="mychecky">My checkbox</label> </> ); }; }, []); return ( <div className="App"> <Row index={3} /> </div> ); }
补充说明
建议取消原代码中checked={checked}的注释,让复选框状态与组件内部的checked状态同步,避免出现状态不一致的问题。
内容的提问来源于stack exchange,提问作者Random Data Monster
相关产品推荐
相关产品推荐

