0

I added MSAL support to my React application. But now I want to add Redux for state management. It seems I have to wrap the App with both the AuthProvider component as well as the Redux Provider component. I'm not familiar with the syntax for how the AuthProvider defines its default export. So when i try to call commbine the AuthProvider doesn't seem to be defined in a way that combine can access it. How do I structure my code so I can accomplish both?

Below is my current code with the some details removed for brevity.

Index.js

ReactDOM.render(
  <React.StrictMode>
      <App />
  </React.StrictMode>,
  document.getElementById('root')
);

App.js

import AuthProvider from "./AuthProvider";

function App(props) {
  return (
    <div className="App">
      <React.Fragment>
        <Router>
          <NavigationMenu
            isAuthenticated={props.isAuthenticated}
            authButtonMethod={props.isAuthenticated ? props.onSignOut.bind(this) : props.onSignIn.bind(this)}
            user={props.account} />
          <Container>
            <Switch>
              <Route exact path="/" isAuthenticated={props.isAuthenticated} render={(props) => <Home {...props} isAuthenticated={props.isAuthenticated} />} />
              <ProtectedRoute path="/configuration" component={Configuration} isAuthenticated={props.isAuthenticated}></ProtectedRoute>
              <ProtectedRoute path="/otherComponent" component={OtherComponent} isAuthenticated={props.isAuthenticated}></ProtectedRoute>
            </Switch>
          </Container>
        </Router>
      </React.Fragment>
    </div>
  );
}

export default AuthProvider(App);

AuthProvider.js

export default AuthComponent =>
    class AuthProvider extends Component {
        // lots of code skipped here
        render() {
            return (
                <Provider store={store}>
                    <AuthComponent
                        {...this.props}
                        account={this.props.account}
                        isAuthenticated={this.props.isAuthenticated}
                        error={this.props.error}
                        graphProfile={this.props.graphProfile}
                        onSignIn={() => this.onSignIn(useRedirectFlow)}
                        onSignOut={() => this.onSignOut()}
                    />
                </Provider>
            );
        }
    };

const mapStateToProps = (state) => {
    return {
        auth: state.authReducer
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        setError: (error) => {
            dispatch(setError(error));
        },
        setAuth: (account) => {
            dispatch(setAuth(account));
        },
        setGraphProfile: (graphProfile) => {
            dispatch(setGraphProfile(graphProfile));
        }
    }
};

connect(mapStateToProps, mapDispatchToProps)(AuthProvider); // <-- This is the line that breaks

1 Answer 1

1

This is not how you set up authentication in a React project at all. Use https://reactjs.org/docs/create-a-new-react-app.html#create-react-app to see how a React project is structured. Try this:

class AuthProvider extends Component {
    // lots of code skipped here
    render() {
        return (
                <AuthComponent
                    {...this.props}
                    account={this.props.account}
                    isAuthenticated={this.props.isAuthenticated}
                    error={this.props.error}
                    graphProfile={this.props.graphProfile}
                    onSignIn={() => this.onSignIn(useRedirectFlow)}
                    onSignOut={() => this.onSignOut()}
                />
        );
    }
};
const mapStateToProps = (state) => {
return {
    auth: state.authReducer
}
};

const mapDispatchToProps = (dispatch) => {
return {
    setError: (error) => {
        dispatch(setError(error));
    },
    setAuth: (account) => {
        dispatch(setAuth(account));
    },
    setGraphProfile: (graphProfile) => {
        dispatch(setGraphProfile(graphProfile));
    }
}
};

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

Provider store={store} needs to wrap your root component and not AuthProvider. Read this https://reacttraining.com/react-router/web/guides/quick-start and the Redux documentation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.