Search code examples
reactjsredux

Data on redux store return to initial state


For example, I store navigate on redux store when the app start:

//in App.js file
import { useNavigate } from 'react-router-dom' 

const App = () => {
   const navigate = useNavigate();

   useEffect(() => {
      dispatch(addNavigate(navigate))
   }, [dispatch, navigate]); 
}

And when I use useSelector to select navigate in redux store in another component, it returns undefined. How can I fix it (if I am not use useNavigate directly in this component) and why navigate object became initial state?


Solution

  • From the Redux Docs:

    It is highly recommended that you only put plain serializable objects, arrays, and primitives into your store. It's technically possible to insert non-serializable items into the store, but doing so can break the ability to persist and rehydrate the contents of a store, as well as interfere with time-travel debugging.

    If you are okay with things like persistence and time-travel debugging potentially not working as intended, then you are totally welcome to put non-serializable items into your Redux store. Ultimately, it's your application, and how you implement it is up to you. As with many other things about Redux, just be sure you understand what tradeoffs are involved.

    With all that said, if you still want to add the navigate function from the useNavigate hook you would only be able to get a valid defined value for navigate if it is called in a child component of BrowserRouter from react-router-dom.

    So in the top level component this wouldn't work, instead we'd need something like this for your App.js:

    import { BrowserRouter } from 'react-router-dom'
    import createStore from './createReduxStore'
    
    const store = createStore()
    
    const App = () => (
      <BrowserRouter>
        <Provider store={store}>
          <Content />
        </Provider
      </BrowserRouter>
    )
    

    Then in your Content component you can do what you initially intended:

    import { useNavigate } from 'react-router-dom' 
    
    const Content = () => {
       const navigate = useNavigate();
    
       useEffect(() => {
          dispatch(addNavigate(navigate))
       }, [navigate]); 
    }