i have several components on the left side. I am running map on them. Each component has a switch.so on the basis of component id after clicking on switch a list of checkboxes open at right side. then again i am also running map on checkboxes because this data is coming from backend. for example component-1 have list of checkboxes with the following name. checkbox-1 checkbox-2 if i select the checkbox-1 and then click on component-2 switch, so by this component-2 list of checkboxes will show. the issue is component-2 checkbox name also will be checked if component-2 have checkbox name same like component-1. how to keep them unique? i want each component checkbox selection to be unique. this is one i did so far. (1) i am passing key to components.so whenever id change react rerender the ui.but its not working. (2) currently my checkbox state is in parent component,i looked into react documentation, according to it the state should be local to component.i move the checkbox state into checkbox component then my issue was fixed. But i need checkbox selection in parent because i am sharing this with other components. (3) then i implement the redux-saga. but still same issue, then i implemented context api, this also didn't resolve my issue.
i am sharing my handlechange code. this is how managing them.
const handleChange = event => {
const { name, checked } = event.target;
if (checked) {
setCheckedItems({ ...checkedItems, [name]: true });
} else {
const { [name]: deletedItem, ...updatedCheckedItems } = checkedItems;
setCheckedItems(updatedCheckedItems);
}
};
(4) then i thought maybe i should make a data structure like so, each component unique id should have its own checkbox selection when user checked any checkbox. this is that code.
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,
};
});
};
but this one also didn't resolve my issue. this also code currently in context.js now i am sharing my how my component looks alike.
(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>
whenever user click on component switch i am updating this state. feedback then on the basis of id inside feedback i am opening checkbox component.
the component NewFeedback is the component where checkbox component is, with name of sidebar.js
<SideBar
bow={bow}
checkedItems={checkedItems}
handleSelectAll={handleSelectAll}
handleChange={handleChange}
allSelected={allSelected}
assignmentId={markingData.question_submission}
assignmentIndex={assignmentIndex}
checkboxIndex={checkboxIndex}
/>
this is my sidebar.js code
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= />
<Box style=>
<FormGroup>
<FormControlLabel
style=
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= />
</div>
);
})}
</Box>
</Paper>
);
};
sorry i cant make sandbox because my actualy codebase is pretty big. here's my ui images for better understanding.
Aucun commentaire:
Enregistrer un commentaire