React Redux子组件复选框状态独立控制问题
解决方案:让每个复选框独立维护Redux状态
问题根源在于你当前的Redux状态是单个布尔值,所有子组件都绑定同一个状态值,导致点击任意复选框都会同步所有组件的选中状态。要实现独立状态,需要将Redux状态改为存储每个复选框id对应的选中状态,具体修改如下:
1. 修改Redux Reducer
将初始状态从单个布尔值改为空对象,键为复选框的id,值为对应的选中状态(布尔值)。处理SET-CHECKBOX动作时,仅切换当前id对应的状态,保留其他id的状态:
const checkboxReducer = (state = {}, action) => { switch(action.type) { case 'SET-CHECKBOX': const targetId = action.payload; return { ...state, [targetId]: !state[targetId] // 切换目标id的选中状态,未存在则默认设为true } default: return state } }; export default checkboxReducer;
2. 调整子组件的状态绑定
在Daily组件中,不再获取整个Redux状态,而是获取当前组件对应id的选中状态,默认未选中时为false:
const Daily = ({ daily, character_id }) => { const { dailyName, id } = daily; // 获取当前id对应的选中状态,默认未选中 const isChecked = useSelector(state => state.checkbox[id] || false) const dispatch = useDispatch() const deleteDaily = async (id) => { const dailyDoc = doc(db, `charactersDailies/${character_id}/dailies`, id) await deleteDoc(dailyDoc) window.location.reload(false) } return ( <div className="dailyContainer"> <input className="dailyCheckbox" id={daily.id} type="checkbox" checked={isChecked} onChange={() => dispatch(setCheckboxAction(daily.id))} /> <label className="dailyName" htmlFor={daily.id}> <h4 className="dailyName">{dailyName.toUpperCase()}</h4> </label> <h4 className="deleteDailyBTN" onClick={() => deleteDaily(id)}> ✕ </h4> </div> ) }; export default Daily;
3. Action无需修改
你的setCheckboxAction已经正确传递了目标复选框的id,保持原代码即可:
export const setCheckboxAction = (id) => { return { type: 'SET-CHECKBOX', payload: id } };
修改完成后,每个复选框的选中状态会独立存储在Redux的对象中,点击单个复选框只会切换自身的状态,其他复选框不受影响。如果需要页面刷新后保留状态,还需配合redux-persist等工具实现Redux状态持久化。
内容的提问来源于stack exchange,提问作者lp90
相关产品推荐
相关产品推荐

