Search code examples
reactjsredux-toolkit

how do i use reducer to update a global variable


I need to pass a variable between two files, this variable will store data(userId) gotten from file one(fetched from an api) so that I can use the variable as a parameter in an endpoint in file two. I have used redux toolkit to create a global state but I can not figure out how to use reducers(from a third file slice.js) to update the global state to the data gotten from file one . I actually do not know how to go about this at all.

file one : inside this file ,there are buttons rendered dynamically from an api that leads to another page when any of the buttons is clicked. On this other page , there is gonna be some information displayed depending on the id gotten.

const [usersData, setUsersData] = userState([]);

useEffect({
fetchData()
});

export default function FileOne(){
return(
<>
  {usersData.map(userData => (
    <Link to='/fileTwo'>
       <button>{userData.id}</button>
    </Link>
  )}
</>
)
}

so i have used redux toolkit to create a global variable

slice.js:

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
    userId:0
    // Your global state properties here (e.g., count: 0, data: [])
};

 export const idSlice = createSlice({
    name: 'id',
    initialState,
    reducers: {
        getUserId(state){
          
        },
        // Reducer functions to update the state (e.g., increment(state) { ... })
    },
});
export const { getUserId} = idSlice.actions;
export default idSlice.reducer; 

what i need help with is how i'm gonna update userId(the global state)to each user's Id depending on the button clicked inside file one


Solution

  • If you are wanting to set a selected user id into the state then these are the changes/additions I'd suggest.

    • Add a new setUserId action to set the currently selected userId
    • Dispatch the setUserId action in the button's onClick handler
    • Read the current userId state value in the target component

    Example:

    const initialState = {
      userId: null
      // Your global state properties here (e.g., count: 0, data: [])
    };
    
    export const idSlice = createSlice({
      name: 'id',
      initialState,
      reducers: {
        ....,
        setUserId: (state, action) => {
          state.userId = action.payload;
        },
      },
    });
    
    export const {
      ....,
      setUserId,
    } = idSlice.actions;
    
    import { useDispatch } from 'react-redux';
    import { setUserId } from '../path/to/idSlice;'
    
    export default function FileOne() {
      const dispatch = useDispatch();
    
      return usersData.map(userData => (
        <Link key={userData.id} to='/fileTwo'>
          <button onClick={() => dispatch(setUserId(userData.id))}>
            {userData.id}
          </button>
        </Link>
      );
    }
    
    import { useSelector } from 'react-redux';
    
    const FileTwo = () => {
      const selectedUserId = useSelector(state => state.id.userId);
    
      ...
    };
    

    For what it's worth this seems like rather transient state and likely doesn't need to be anything stored in the Redux store. Since you are using a Link component (assumed React-Router library usage here) and effecting a navigation action you could likely just include the user id in the navigation action, either in the URL path, i.e. "/fileTwo/:userId", or in the route state.

    • Passing userData.id in route state:

      import { Link } from 'react-router-dom';
      
      export default function FileOne() {
        const dispatch = useDispatch();
      
        return usersData.map(userData => (
          <Link key={userData.id} to='/fileTwo' state={{ userId: userData.id }}>
            {userData.id}
          </Link>
        );
      }
      
      import { useLocation } from 'react-router-dom';
      
      const FileTwo = () => {
        const { state } = useLocation();
        const { userId } = state ?? {};
      
        ...
      };
      
    • Passing userData.id in URL path segment:

      <Route
        path="/fileTwo/:userId?"
        element={<FileTwo />}
      </Route>
      
      import { Link } from 'react-router-dom';
      
      export default function FileOne() {
        const dispatch = useDispatch();
      
        return usersData.map(userData => (
          <Link key={userData.id} to={`/fileTwo/${userData.id}`}>
            {userData.id}
          </Link>
        );
      }
      
      import { useParams } from 'react-router-dom';
      
      const FileTwo = () => {
        const { userId } = useParams();
      
        ...
      };