Search code examples
reactjsreduxredux-toolkit

how to use redux toolkit if your react app has several routes?


I'm creating a simple react app, I'm also using redux toolkit for state management, however, the normal RTK functions aren't working properly in my app. it contains 2 seperate components, each having its own route. I've read the docs and they have created a single page react app so there are no real routes involved. Do I need to know something more? is RTK not enough for this purpose.

also one of the components will modify the state and the other one reads it. here is the code:

index.js file:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {configureStore} from '@reduxjs/toolkit';
import {Provider} from 'react-redux';
import userreducer from './features/user.js'; 
import themereducer from './features/theme.js';
import {BrowserRouter} from 'react-router-dom';

let firststore=configureStore({
  reducer:{     
    user: userreducer,   
    theme: themereducer,
  }   
});



const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={firststore}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
  
);

this is app.js file:

import Profile from "./components/profile";
import Login from './components/login.js';
import {Route,Routes} from 'react-router-dom';

function App() {
  return (
    <>
      <Routes>
        <Route path="/" element={<Profile/>}/>
        <Route path="/log" element={<Login/>}/>
      </Routes>
      
    </>
      
    
  );
}

export default App;

slices:

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

export let userslice= createSlice({
    name:"usernameslice",  
    initialState: { value: { name:"", age: 0, email:""}},   
    reducers:{    
        logn: (state,action)=>{
           state.value=action.payload;
        },

        logout: (state,action)=>{
           state.value={name:"",age:0,email:""};
        },
    }
});


     
export const {logn,logout} = userslice.actions;   

export default userslice.reducer;

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

export const themeslice=createSlice({
    name:"theme",
    initialState:{ value: " "},
    reducers:{
        changecolor: (state,action)=>{
            state.value=action.payload;
        }   
    }
});

export const {changecolor} = themeslice.actions;

export default themeslice.reducer;

login component:

import {logn, logout} from '../features/user.js';
import {useDispatch} from 'react-redux';
import { changecolor } from '../features/theme.js';
import React from 'react';
import {useState} from 'react';


let Login = () => {

    let [col,setCol]= useState("");
    let disp=useDispatch();



    return ( 
        <div>
          <button onClick={()=>{
            disp(logn({name:"abdullah",age:12,email:"[email protected]"})); 
          }}>Login</button>
          <button onClick={()=>{
            disp(logout());
          }}>logout
          </button>
          <input type='text' onChange={(e)=>{
            disp(changecolor(e.target.value));
          }}>
          </input>
        </div>
        

    );
}
 
export default Login ;

profile component:

import {useSelector} from 'react-redux';

let Profile  = () => {

    let uwe=useSelector((state)=>{ return state.user.value}); 
    let coloriser=useSelector((state)=>{return state.theme.value});
    console.log(uwe);
    console.log(coloriser);


    return (  
        <div style={{color:coloriser}}> 
            <h1>Profile page</h1>
            <p>name: {uwe.name}</p>
            <p>age: {uwe.age}</p>
            <p>email:{uwe.email}</p>
        </div>
    );
};


 
export default Profile;

do tell me if any clarification is needed.. thank you!


Solution

  • as far as i can see the code is working as intended, the state is updated correctly, but you are not are not using the Browser router (react router) to navigate from "/log" to "/", i presume you are using the back arrow in the browser or refreshing the page which will reload the App and the state will be reinitialized. Either persist the state, so that even if you refrech the state will be preserved, or use react router's navigation system :

    <Link to "/">Profile</Link>
    

    or simply redirect to "/" after the login to see the changes in the state:

    import { logn, logout } from "../features/user.js";
    import { useDispatch, useSelector } from "react-redux";
    import { changecolor } from "../features/theme.js";
    import React from "react";
    import { useState } from "react";
    import { useNavigate } from "react-router-dom";
    
    let Login = () => {
    let [col, setCol] = useState("");
    let uwe = useSelector((state) => {
        return state.user.value;
    });
    const navigate = useNavigate();
    let disp = useDispatch();
    
    return (
        <div>
            <button
                onClick={() => {
                    disp(
                        logn({
                            name: "abdullah",
                            age: 12,
                            email: "[email protected]",
                        })
                    );
                    navigate("/");
                }}
            >
                Login
            </button>
            <button
                onClick={() => {
                    disp(logout());
                }}
            >
                logout
            </button>
            <input
                type="text"
                onChange={(e) => {
                    disp(changecolor(e.target.value));
                }}
            ></input>
        </div>
    );
    };
    
    export default Login;