我的左侧有几个组件。我正在对他们运行地图。每个组件都有一个基于组件 id 的 switch.so,单击 switch 后,右侧将打开一个复选框列表。 然后我还在复选框上运行地图,因为这些数据来自后端。 例如,组件 1 具有具有以下名称的复选框列表。 复选框-1 复选框-2 如果我选择复选框 1,然后单击组件 2 开关,那么将显示此组件 2 的复选框列表。 问题是,如果组件 2 的复选框名称与组件 1 相同,组件 2 的复选框名称也会被检查。 如何保持它们的独特性? 我希望每个组件复选框选择都是唯一的。 这是我到目前为止所做的。 (1) 我将密钥传递给组件。因此,每当 id 更改时,都会重新渲染 ui。但它不起作用。 (2)目前我的复选框状态位于父组件中,我查看了反应文档,根据它,状态应该是组件本地的。我将复选框状态移动到复选框组件中,然后我的问题得到解决。但我需要在父级中选择复选框,因为我正在与其他组件共享它。 (3) 然后我实现 redux-saga。但仍然是同样的问题,然后我实现了 context api,这也没有解决我的问题。
我正在分享我的handlechange代码。这就是管理它们的方式。
const handleChange = event => {
const { name, checked } = event.target;
if (checked) {
setCheckedItems({ ...checkedItems, [name]: true });
} else {
const { [name]: deletedItem, ...updatedCheckedItems } = checkedItems;
setCheckedItems(updatedCheckedItems);
}
};
(4) 然后我想也许我应该制作一个像这样的数据结构,当用户选中任何复选框时,每个组件唯一的 id 应该有自己的复选框选择。 这就是那个代码。
const handleChange = (event, componentId, index) => {
const { name, checked } = event.target;
setCheckboxIndex(index);
// Update the state using the componentId to ensure uniqueness
setCheckedItems(prevItems => {
// Get the previous state for the component or initialize it
const componentState = prevItems[componentId] || { checkboxes: {} };
// Clone the previous component state
const updatedComponentState = { ...componentState };
if (checked) {
updatedComponentState.checkboxes = {
...updatedComponentState.checkboxes,
[name]: true,
};
} else {
// Remove the checkbox from the component's state
const {
[name]: deletedItem,
...updatedCheckboxes
} = updatedComponentState.checkboxes;
updatedComponentState.checkboxes = updatedCheckboxes;
}
// Update the overall state with the new component state
return {
...prevItems,
[componentId]: updatedComponentState,
};
});
};
但这也没有解决我的问题。 这也是当前在 context.js 中的代码 现在我正在分享我的组件看起来如何相似。
(toggleMenu === 'feedback' &&
Object.keys(feedback).includes(String(q.id))) ||
(q.question.question_type === 'assignment' &&
toggleAll === 'auto') ? (
<Grid item xs={5} className={classes.questionWrapper} key={q.id}>
<NewFeedback
key={q.id}
assignmentIndex={qidx}
markingData={automatedMarkingData}
questionId={q.question.id}
qId={qId}
fetchMarkingData={fetchMarkingData}
status={assignmentStatus}
/>
</Grid>
每当用户单击组件开关时,我都会更新此状态。 反馈 然后根据内部反馈的 id,我打开复选框组件。
组件NewFeedback是checkbox组件所在的组件,名称为sidebar.js
<SideBar
bow={bow}
checkedItems={checkedItems}
handleSelectAll={handleSelectAll}
handleChange={handleChange}
allSelected={allSelected}
assignmentId={markingData.question_submission}
assignmentIndex={assignmentIndex}
checkboxIndex={checkboxIndex}
/>
这是我的 sidebar.js 代码
import React, { useContext } from 'react';
import {
Box,
Checkbox,
Divider,
FormControlLabel,
FormGroup,
LinearProgress,
Paper,
Typography,
} from '@material-ui/core';
import styles from './styles.css';
import { LessonContext } from '../../LessonViewer/GoProgressQuizResult/Context';
export const SideBar = ({
bow,
checkedItems,
handleSelectAll,
handleChange,
allSelected,
assignmentId,
assignmentIndex,
checkboxIndex,
}) => {
return (
<Paper elevation={0} className={`${styles.FeedbackSideMenu}`}>
<Box p={1}>
<Typography align="center">
<b>All BOW</b>
</Typography>
</Box>
<Divider style={{ margin: '5px 0' }} />
<Box style={{ overflowY: 'scroll' }}>
<FormGroup>
<FormControlLabel
style={{ display: 'flex', justifyContent: 'space-evenly' }}
control={
<Checkbox
checked={allSelected}
onChange={handleSelectAll}
name="selectAll"
color="primary"
/>
}
label="Select All"
/>
</FormGroup>
{bow.map((v, index) => {
// const isChecked =
// (checkedItems[assignmentId] &&
// checkedItems[assignmentId].checkboxes[v.bow_name]) ||
// false;
// console.log('isChecked', isChecked);
return (
<div key={v.id}>
<Box className={`${styles.FeedbackOption}`}>
<Box
display={'flex'}
justifyContent="space-between"
alignItems="center"
>
<Checkbox
id={v.id}
// checked={checkedItems[`${v.bow_name}_${v.id}`] || false}
checked={checkedItems[v.bow_name] || false}
// checked={label === v.bow_name ? true : false}
// checked={isChecked}
onChange={e => handleChange(e, assignmentId, index)}
name={v.bow_name}
color="primary"
/>
<Typography>
<b>{v.bow_name}</b>
</Typography>
<Box bgcolor={`${v.color}`} width={20} height={20} />
</Box>
<Typography>
<small>{v.sum_count} count</small>
</Typography>
<LinearProgress
variant="determinate"
value={v.sum_count ? v.sum_count : 0}
/>
</Box>
<Divider style={{ margin: '5px 0' }} />
</div>
);
})}
</Box>
</Paper>
);
};
我解决了这个问题。 NewFeedback 组件位于地图内,因此我只需将我的提供程序包装在 NewFeedback 组件上的地图内。这样每个组件都有自己的状态和复选框选择。