passing redux store in props coming as undefined?

2020-02-16 02:52发布

问题:

When I am passing the store from let store = createStore(myReducer); in props to other component it is coming undefined. this is happening whenI am using react-router-dom but without that it is coming alright. The route part

the route is in App component

<BrowserRouter>
        <div>
            <Route path={"/layout"} component={Home} />
            <Route path={"/form"} component={UserForm} />
            <Route exact  path={"/"} component={this.layout}   />
        </div>
    </BrowserRouter

layout method

  layout(){
    return (
        <Layout store={this.props.store} />
    );
  }

I am passing the store in the app component like this

const renderAll = () => {
    console.log("inside render all" ,store);
    ReactDOM.render(
      <App store={store} />,
      document.getElementById('root')
    );
}

this store is going to body component from layout component like this

 <Body ChangeName={this.handleChangeName} store = { this.store}  s_key={this.state.inputkey} />

in body component I am fetching from from a api which is running in the node.js server in the componentWillMount()

 fetch('/api/get/all',{
    headers : {
    'content-Type': 'application/json',
    }
 }).then((res)=>{
      console.log(res);
      return res.json();
 }).then(users =>{
      this.store.dispatch({
        type :"FETCH_ALL",
        data : users
      })
      this.setState({
        user: users
      })
      // console.log(this.state.user);
 });

I am getting error in the map function

 {this.store.getState().user.map(u => {
       return  <UserDiv name={u.name} age={u.age} location={u.location} gender={u.gender} job={u.job} />;
  })}

error

Cannot read property 'map' of undefined

the weird part is when I am doing without the route it is coming alright thanks in advance

回答1:

Firstly in order to get the updated state from the store, you need to subscribe to it like

const unsubscribe = store.subscribe(() => {
    store.getState();
})

and hence it is not a React way to handle changes.

Secondly, when you are passing store to Layout component, it is entirely possible that you did not bind the layout function and hence this.props.store is undefined.

In order to use Redux the react way, you can make use of Provider and connect methods

import { Provider } from 'react-redux';
const renderAll = () => {
    console.log("inside render all" ,store);
    ReactDOM.render(
      <Provider store={store}>
          <App />
     </Provider>,
      document.getElementById('root')
    );
}

and then your Routes can simply be

and you can call Body component from Layout like

 <Body ChangeName={this.handleChangeName} s_key={this.state.inputkey} />

and connect the body component like

const mapStateToProps = (state) => {
   user: state.user
}

export default connect(mapStateToProps)(Body)

Make sure to use the connected Body component in your Layout component.

After this you can use user state in Body component like

{this.props.user.map(u => {
       return  <UserDiv name={u.name} age={u.age} location={u.location} gender={u.gender} job={u.job} />;
})}

In case the user value is undefined in the redux store initially, you need to add a check in the Body component before using it like

{this.props.user && this.props.user.map(u => {
       return  <UserDiv name={u.name} age={u.age} location={u.location} gender={u.gender} job={u.job} />;
})}