Search code examples
reactjsreduxuse-effect

Solving problem of component failing to rerender after refresh


I have a Dashboard component that receives state from a reducer and then renders account info for a user based on state. The component is rendering just fine on the first render. However, when I refresh the page, everything goes away, nothing is rendering. I thought it might be a problem with my useEffect hook and that this problem could possibly be solved by placing some value inside the dependency array there. However, I'm realizing that even if the problem were that, the portions of the component JSX elements that are not dependent on the useEffect hook should still render. Not even that is happening, I'm getting absolutely nothing on refresh. How can I resolve this?

Here is a link to the project on Github: https://github.com/jevoncochran/Food-Truck-TrackR

Here is the component:

const Dashboard = props => {
    const [accountInfo, setAccountInfo] = useState({});

    useEffect(() => {
            axiosWithAuth()
                .get(`/operator/${props.id}`)
                .then(res => {
                    // console.log(res);
                    setAccountInfo(res.data);
                })
                .catch(err => console.log(err))
    }, [props.id])

    return (
        <div>
            <h1>This is the Dashboard component</h1>
            <h2>Welcome, {accountInfo.username}</h2>
            <h3>Your Trucks</h3>
            {accountInfo.trucks && accountInfo.trucks.map(truck => (
                <div key={truck.id}>
                    <p>{truck.name}</p>
                    <p>{truck.cuisine_type}</p>
                    <p>{truck.physical_address}</p>
                    <br/>
                </div>
            ))}
        </div>
    )
}

const mapStateToProps = state => {
    return {
        id: state.account.id,
        username: state.account.username,
        email: state.account.email
    }
}

export default connect(mapStateToProps, {})(Dashboard);

EDIT: This is how the Dashboard component is being rendered. After reading over folks comments, it seems like upon refresh, I'm losing state.account.id which is causing me to lose the dynamicRoute in App.js, which causes the Dashboard component to fail to render. Anyone see a solution for this problem:

function App(props) {
  console.log(props);
  const dynamicRoute = `/api/vendor/${props.accountId}`

  return (
    <Router>
      <div className="App">
        <Route exact path="/login" component={Login} />
        <Route exact path="/register" component={Register} />
        <PrivateRoute path={dynamicRoute} component={Dashboard} />
      </div>
    </Router>
  );
}

Solution

  • There were a couple ways to solve this problem. One of them was to have an action that would make an API call to retrieve the info I needed for the Dashboard component and run that action if ever the redux state was coming back undefined, which is what happens on refresh. There's also redux-persist. I ultimately ended up using redux-persist to solve this problem, for which documentation can be found here: https://github.com/rt2zz/redux-persist. Here is the code from index.js:

    The relevant imports:

    import { createStore, applyMiddleware } from "redux";
    import { Provider } from "react-redux";
    import { persistStore, persistReducer } from "redux-persist";
    import storage from "redux-persist/lib/storage";
    import { PersistGate } from "redux-persist/integration/react";
    
    // set up to persist redux state on refresh
    const persistConfig = {
        key: 'root',
        storage
    };
    
    const persistedReducer = persistReducer(persistConfig, truckReducer);
    
    // async middleware (thunk) and logger has to go here
    let store = createStore(persistedReducer, applyMiddleware(thunk, logger));
    
    let persistor = persistStore(store);
    
    ReactDOM.render(
        <Provider store={store}>
            {/* wrap component in PersistGate for redux persist to take effect */}
            <PersistGate loading={null} persistor={persistor}>
                <Router>
                    <App />
                </Router>
            </PersistGate>
        </Provider>, 
        document.getElementById('root')
    );