我在应用程序中使用react redux/toolkit,我认为我可以用redux状态管理同级组件之间的共享状态。为此,我实现了一个带有state和reducer的redux切片,并试图通过调用reducer来更新状态。它适用于一个组件,但对于另一个同级组件,初始状态只是获取的,看不到更新的值。没有保留状态的api。数据值过去保存在本地存储中,但它有局限性,所以我需要将数据保存在冗余状态中
Redux文件:
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;
母组件
....
/* 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,
}),
};
}
循环调用的子组件:
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>)}
.......;
};
更新状态对第一个组件有效,但第二个子组件无法访问它,它只显示默认值。我的设计有错吗?
感谢
最后,我可以弄清楚代码中的问题所在。首先,我通过用PersistGate包装App组件来监控redux/toolkit中的prevState、action、nextState,之后我注意到prevState被action.payload取代,数组中的旧值也被删除。我已经根据prevState和action.payload(状态参数(更改了reducer函数,并根据有效载荷中传递的值更新了prevState。我不得不将一些逻辑转移到reducer中以构成新状态:
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]
},