Search code examples
javascriptreactjslocal-storageredux-toolkitglobal-state

Why store.getState() doesn't update in reduxjs/toolkit


Does anyone know why though through the "useSelector" hook, the updated state is available, but the store.getState() doesn't update?

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
    baseUrl: "http://example.com/" 
}

function changeToLocal(state) {
    return {...state, baseUrl: "https://localhost:345345/"}
}
function changeToGlobal(state) {
    return { ...state, baseUrl: "http://example.com/"}
}


const ApiConfig = createSlice({
    name: 'changeBaseURL',
    initialState,
    reducers: {
        changeToLocal,
        changeToGlobal,
    }
})

export const {
    changeToLocal: changeToLocalAction,
    changeToGlobal: changeToGlobalAction,
} = ApiConfig.actions

export default ApiConfig.reducer;

Here after dispatching, through the "useSelector" hook, the updated state is recieved:

const Header = () => {
    const dispatch = useDispatch())
    const CurrentBaseURL= useSelector(state => state.changeBaseURL.baseUrl)
    console.log("🚀 ~ file: header.jsx ~ line 11 ~ Header ~ CurrentBaseURL", CurrentBaseURL)
    const changeBaseURl = (e) => {
        if (e.target.value === "local") {
            dispatch(changeToLocalAction())
        } else if (e.target.value === "global"){
            dispatch(changeToGlobalAction())
        }
    }
...

:

But when I wanted to use the updated baseURL in my APIConfig file, I realized that it didn't update:

import { Toast } from '../../helpers/Toast';
import axios from 'axios';
import store from '../../redux/store';
import { useSelector } from 'react-redux';
    const instance = axios.create({
        baseURL: "htttp://example.com",
        timeout: 10000,
        headers: { "x-Custom-Header": "foobar" }
    })
    instance.interceptors.response.use(response => {
        if (response.headers["token-user"]) {
            localStorage.setItem("token", response.headers["token-user"]);
        }
        if (response.data && response.data.statusIcon && response.data.status) {
            Toast(response.data.statusIcon, response.data.status);
        }
        return response;
    }, err => {
        const expectErrors = err.response && err.response > 400 && err.response.status < 500;
        if (!expectErrors) {
            console.log(err);
        return Promise.reject(err);

    });
    export default instance;

The above config is used like so:

import Api from '../../../utils/request/api/Api'

export const GetDisposablePassword = (nationalCode) => {
    return Api.post(`api/Auth/GetDisposablePassword`, { nationalCode })
};

Does anyone know how to handle this problem by a principal method?


Solution

  • I solved this problem using locagStorage instead of @reduxjs/toolkit like so:

    import { currentBaseURL, localBaseURL, officialBaseURL } from '../../utils/request/Request';
    
    
    const Header = () => {
        const changeBaseURl = (e: any) => {
            if (e.target.value === "local") {
                localStorage.setItem("baseURL", JSON.stringify({
                    key: e.target.value,
                    value: localBaseURL   
                }));
            } else if (e.target.value === "current") {
                localStorage.setItem("baseURL", JSON.stringify({
                    key: e.target.value
                    value: currentBaseURL
                }));
            } else if (e.target.value === "official") {
                localStorage.setItem("baseURL", JSON.stringify({
                    key: e.target.value,
                    value: officialBaseURL
                }));
            }
        }
    ...
    And in file Request:

    export const currentBaseURL = window.location.origin;
    export const officialBaseURL = "https://exampel.example";
    export const localBaseURL = "https://localhost:7215/";
    
    var baseURL = JSON.parse(localStorage.getItem('baseURL') || '{}');
        if (isEmpty(baseURL)) {
                baseURL = currentBaseURL;
            }
        } else {
            baseURL = baseURL.value;
        }
        
        const instance = axios.create({
            baseURL: baseURL,
            timeout: 10000,
            headers: { "x-Custom-Header": "foobar" }
        })
        instance.interceptors.response.use(response => {
            if (response.headers["token-user"]) {
                localStorage.setItem("token", response.headers["token-user"]);
            }
            if (response.data && response.data.statusIcon && response.data.status) {
                Toast(response.data.statusIcon, response.data.status);
            }
            return response;
        }, err => {
            const expectErrors = err.response && err.response > 400 && err.response.status < 500;
            if (!expectErrors) {
                console.log(err);
            return Promise.reject(err);
    
        });
        export default instance