'How can access redux state in sibling components without using action
I am using react redux/toolkit in my application, I assume that I can manage share state between sibling components with redux state. For this purpose, I have implemented a redux slice with state and reducer, and trying to update the state via calling reducer. It works for one component , but for another sibling components the initial state is just fetched, and can't see updated values. There isn't api for keeping the state. Data value used to be saved in local storage, but it has limitation, so I need to keep data inside redux state
Redux file:
const annotationSlice = createSlice({
name: 'annotation',
initialState: {
localAnnData: []
},
reducers: {
updateLocalAnn: (state, { payload }) => {
state.localAnnData = payload
}
}
});
export const { updateLocalAnn } = annotationSlice.actions;
export const annotationSelector = (state) => state.annotation;
export default annotationSlice.reducer;
Parent component
....
/* loop through each columns of reportData */
const formattedColumns = column.map(
({
Header,
Key,
fieldType /* 'STRING', 'FLOAT' etc */,
dataType,
format /* align: left */,
LinkThrough /* consisting of reportid, parameters and rules passed */,
Annotations /* Annotataion object in the column */,
CustomActions,
}) => {
const isDataTypeArray = dataType?.toLowerCase() === 'array';
if (Annotations) {
const pickListValues = Annotations.value;
const params = Annotations.parameters;
return {
Header,
accessor: Key,
toolbarLabel: Header,
width: 250,
sortable: false,
canSort: false,
disableSortBy: false,
defaultCanSort: false,
Cell: (props) =>
child({
...props,
reportId,
paramsValues,
pickListValues,
params,
viewAnnotationModal,
saveAnnotation,
allColumn:
column /* each column entries passed as allColumn;
reportData.columns */,
label: Annotations.label,
objType: Annotations.obj_type,
data,
// updateLocalAnnData: updateLocalAnnotationData,
// localAnnData,
}),
};
}
Child component which is called in a loop:
export const child = (props) => {
const dispatch = useDispatch();
const { localAnnData } = useSelector(annotationSelector);
const {
row,
params ,
value,
reportId,
column,
paramsValues ,
viewAnnotationModal ,
pickListValues
allColumn
label,
objType,
updateMyAnnData,
data,
} = props;
const setUpdatedValue = (field, val) => {
let annoData = localAnnData;
annoData = annoData?.length ? annoData : data;
annoData = annoData.map((el) =>
el.Titan_BE_ID === row.original.Titan_BE_ID
? { ...el, [field]: val } : el,
);
dispatch(updateLocalAnnData(annoData));
};
const onChange = (e) => {
setUpdatedValue(column.id, e.target.value);
};
return (
<div style={{ display: 'flex' }}>
{!pickListValues && (<div>
<CustomTextBox
param={{
name: column.id,
value: values,
}}
onHandleChange={onChange}
isAnnotationTextbox
placeholderText='Enter Comments'/>
</div>)}
{ pickListValues?.length > 0 && (<div>
<customDropDown
param={{
name: column.id,
values: pickListValues,
}}
onHandleChange={onChange}/>
</div>)}
.......;
};
Updating the state is working for the first component , but the second child component doesn't have access to it, and it just shows the default value. Is there something wrong in my design?
Thanks
Solution 1:[1]
Finally , I could figure out what was the problem in my code. First,I monitored prevState, action, nextState in redux/toolkit via wrapping App component with PersistGate, after that I noticed that prevState is replaced by action.payload, and old values in the array is removed. I have changed the reducer function based on prevState and action.payload (state parameter) and updated prevState based on the values passed in payload. I had to move some logic into reducer for making up new state:
updateLocalAnnData: (state, { payload }) => {
const prevState= [...state.localAnnData];
const keepData = (prevState.length > 0) ? prevState.map(data =>
data.Titan_BE_ID === payload.data.Titan_BE_ID ? {...data,
[payload.field]: payload.val} : data
) : payload.allData.map(data =>
data.Titan_BE_ID === payload.data.Titan_BE_ID ? {...data, [payload.field]: payload.val} : data
);
state.localAnnData = [ ...keepData]
},
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mary |
