问题
DISCLAIMER: This error has been mentioned on stackoverflow before but my case is different.
I have had a problem with the user login which I have explained in this stackOverFlow question. I invite you to go and quickly take a look.
So as I mentioned in that question in my root file I have this:
App.js
class App extends Component {
render() {
const authLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
<Route
path="/home"
name="Home"
render={props => <DefaultLayout {...props} />}
/>
</Switch>
);
const guestLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/register"
name="Register Page"
render={props => <Register {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
</Switch>
);
const currentState = store.getState();
console.log(
"currentState.auth.isAuthenticated: ",
currentState.auth.isAuthenticated
);
return (
<Provider store={store}>
<HashRouter>
<React.Suspense fallback={loading()}>
{console.log(currentState.auth.isAuthenticated)}
{/* TODO: Not sure if this always works. If after the user logsin he gets a blank page and he has to reload to be redirected to home then
this way of routing may need to modified */}
{currentState.auth.isAuthenticated ? authLinks : guestLinks}
</React.Suspense>
</HashRouter>
</Provider>
);
}
}
I have been told that I am accessing the state isAuthenticated incorrectly:
{currentState.auth.isAuthenticated ? authLinks : guestLinks}
That I should access it by using connect(). That was actually the first thing I have tried. It didn't work. But, I took their advice and tried it again:
class App extends Component {
render() {
const authLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
<Route
path="/home"
name="Home"
render={props => <DefaultLayout {...props} />}
/>
</Switch>
);
const guestLinks = (
<Switch>
<Route
exact
path="/"
name="Login Page"
render={props => <Login {...props} />}
/>
<Route
exact
path="/register"
name="Register Page"
render={props => <Register {...props} />}
/>
<Route
exact
path="/404"
name="Page 404"
render={props => <Page404 {...props} />}
/>
<Route
exact
path="/500"
name="Page 500"
render={props => <Page500 {...props} />}
/>
</Switch>
);
const currentState = store.getState();
console.log(
"currentState.auth.isAuthenticated: ",
currentState.auth.isAuthenticated
);
return (
<Provider store={store}>
<HashRouter>
<React.Suspense fallback={loading()}>
{console.log(currentState.auth.isAuthenticated)}
{/* TODO: Not sure if this always works. If after the user logsin he gets a blank page and he has to reload to be redirected to home then
this way of routing may need to modified */}
{/* {currentState.auth.isAuthenticated ? authLinks : guestLinks} */}
{this.props.auth.isAuthenticated ? authLinks : guestLinks}
</React.Suspense>
</HashRouter>
</Provider>
);
}
}
App.propTypes = {
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(mapStateToProps, null)(withRouter(App));
which gives the error I've mentioned:
Could not find "store" in the context of "Connect(withRouter(App))". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(withRouter(App)) in connect options.
which kind of makes sense, since the store is passed root component App.js through the router. So the state of the app shouldn't be accessed in the same way it is accessed in childComponents through connect.
So I have two questions:
QUESTION 1: Why am I getting this error?
QUESTION 2: What is the right way of accessing the state data inside the root component where the link between the redux and react is implemented?
回答1:
QUESTION 1:
I believe you have to wrap withRouter
first.
Try this:
import { connect } from "react-redux";
import { withRouter } from "react-router";
export default withRouter(connect(mapStateToProps, null)(App));
QUESTION 2:
You are mapping the state to props so the correct way to access auth
from your state in your component is this.props.auth
Try to console.log(this.props) in your render and you will see what I mean. Also check the the docs on https://react-redux.js.org/api/connect
Hope this helps
回答2:
ANSWER 1: I think that you should use "connect" on a component called inside Provider. The docs says:
Could not find "store" in either the context or props
If you have context issues,
Make sure you don’t have a duplicate instance of React on the page.
Make sure you didn’t forget to wrap your root or some other ancestor component in <Provider>.
Make sure you’re running the latest versions of React and React Redux.
/*Into App.js*/
return (
<Provider store={store}>
<HashRouter>
<React.Suspense fallback={loading()}>
<ConnectedComponent>
</React.Suspense>
</HashRouter>
</Provider>
);
/*ConnectedComponent.js*/
class ConnectedComponent extends React
{
render(){
{
/* move all your routing and app code Here*/
}
}
//call connect on your ConnectedComponent
export connect(mapStateToProps, null)(ConnectedComponent)
I also think that you don't need to use withRouter because seems that you don't need the ReactRouter props (match, history, location) on your App component.
You can see here wen you should use withRouter: https://reacttraining.com/react-router/web/api/withRouter
ANSWER 2: The connect() function do the job of connecting the Redux store to your React components tree. You should always access to the store data through the props object.
来源:https://stackoverflow.com/questions/60223016/reactjs-what-is-the-proper-way-of-accessing-the-state-data-in-the-root-compone