如何在不使用操作的情况下访问同级组件中的 redux 状态
How can access redux state in sibling components without using action
我在我的应用程序中使用 React redux/toolkit,我假设我可以管理具有 redux 状态的同级组件之间的共享状态。
为此,我实现了一个带有状态和缩减器的 redux 切片,并尝试通过调用缩减器来更新状态。它适用于一个组件,但对于另一个同级组件,初始状态只是获取,并且看不到更新的值。
没有 api 来保持状态。
数据值以前保存在本地存储中,但它有限制,所以我需要将数据保存在 redux state
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(state 参数)更改了 reducer 函数,并根据 payload 中传递的值更新了 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]
},
我在我的应用程序中使用 React redux/toolkit,我假设我可以管理具有 redux 状态的同级组件之间的共享状态。 为此,我实现了一个带有状态和缩减器的 redux 切片,并尝试通过调用缩减器来更新状态。它适用于一个组件,但对于另一个同级组件,初始状态只是获取,并且看不到更新的值。 没有 api 来保持状态。 数据值以前保存在本地存储中,但它有限制,所以我需要将数据保存在 redux state
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(state 参数)更改了 reducer 函数,并根据 payload 中传递的值更新了 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]
},