reactjsreduxhigher-order-components

Using redux state inside HOC in reactjs


In my react app, I have a withAuth HOC which checks if the user is authenticated before the wrapped component is loaded. It looks up the redux store to check auth status and loads the component, if isAuth is true. However, I can't access redux store from the HOC. when I try, I get the following error message on the browser. Any help to overcome this problem is highly appreciated.

enter image description here

withAuth.js

import React, { useState, useEffect } from 'react';
import { setAuth } from '../actions/Actions';
import { connect } from 'react-redux';

function withAuth(WrappedComponent) {
    return (props) => {
        const [isAuth, setAuth] = useState(false);

        useEffect(() => {
            if (props.isAuth) {
                setAuth(true);
            } else {
                props.history.push('/catalog');
            }
        }, [props.history]);

    return isAuth ? <WrappedComponent {...props} /> : <p>Loading..</p>
    };
}

const mapStateToProps = (state) => {
    return {
        isAuth: state.isAuth,
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        setAuth: (status) => dispatch(setAuth(status)),
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(withAuth);

Solution

  • You cannot pass a HOC to connect, you have to pass a function component:

    export default function withAuth(WrappedComponent) {
      const Component = (props) => {
        const [isAuth, setAuth] = useState(false);
    
        useEffect(() => {
          if (props.isAuth) {
            setAuth(true);
          } else {
            props.history.push('/catalog');
          }
        }, [props.history, props.isAuth]);//forgot dependency here
    
        return isAuth ? (
          <WrappedComponent {...props} />
        ) : (
          <p>Loading..</p>
        );
      };
      const mapStateToProps = (state) => {
        return {
          isAuth: state.isAuth,
        };
      };
    
      const mapDispatchToProps = (dispatch) => {
        return {
          setAuth: (status) => dispatch(setAuth(status)),
        };
      };
    
      return connect(
        mapStateToProps,
        mapDispatchToProps
      )(Component);
    }