React中createPortal渲染的受控子组件不随父状态更新重渲染
问题解决:Portal渲染的单选按钮未同步选中状态
核心问题分析
通过createPortal渲染的子组件,虽然父组件状态已更新,但子组件未触发重渲染,导致单选按钮的checked属性无法同步最新状态。这通常是因为子组件没有正确响应props变化,或者props的引用稳定性导致重渲染逻辑失效。
具体解决方案
直接绑定父组件状态到单选按钮
子组件必须直接使用父组件传递的selectedValue来设置单选按钮的checked属性,确保状态变化能直接反映到DOM上。示例代码:import { createPortal } from 'react-dom'; interface RadioOption { value: string; label: string; } interface RadioListProps { options: RadioOption[]; selectedValue: string; onSelect: (value: string) => void; } export default function RadioList({ options, selectedValue, onSelect }: RadioListProps) { return createPortal( <div> {options.map(option => ( <label key={option.value}> <input type="radio" name="radio-group" value={option.value} checked={selectedValue === option.value} onChange={() => onSelect(option.value)} /> {option.label} </label> ))} </div>, document.body ); }确保props引用稳定(若使用React.memo)
如果子组件用React.memo包裹优化性能,需自定义props比较函数,确保selectedValue变化时能触发重渲染:import { memo } from 'react'; const RadioList = memo( ({ options, selectedValue, onSelect }: RadioListProps) => { // 组件内容同上 }, (prevProps, nextProps) => { // 仅当selectedValue或选项列表真的变化时才触发重渲染 if (prevProps.selectedValue !== nextProps.selectedValue) return false; if (prevProps.options.length !== nextProps.options.length) return false; return prevProps.options.every((opt, idx) => opt.value === nextProps.options[idx].value); } );通过key强制子组件重渲染
在父组件调用子组件时,将selectedValue作为key传递,状态变化时key更新会强制子组件重新渲染:// 父组件代码片段 <RadioList options={options} selectedValue={selectedValue} onSelect={handleSelect} key={selectedValue} />
内容的提问来源于stack exchange,提问作者João Pedro
相关产品推荐
相关产品推荐

