'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