简体   繁体   中英

Redux mapStateToProps returns undefined

Redux is successfully storing and updating state. The reducers are seemingly working correctly. I'm able to use this.props.dispatch . However, when it actually comes to detailing that information (ie this.props.array I always seem to get undefined.

Reducer:

export default function array(state = {}, action) {
    switch (action.type) {
      case "UPDATE_ARRAY":
        state.array = action.array
        return state;
      default:
        return state;
  }
}

State-aware component:

  constructor(props) {
    super(props);
    this.state = {
      array: array
    }
  }

--

  self.props.dispatch({
    type: 'UPDATE_ARRAY',
    array: array
  })

--

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

    export default connect(mapStateToProps)(Component);

This only seems to be able to save state btw when I define an empty array. This doesn't seem right, I thought the intention of Redux was a self-contained store? Updating a variable seems to defeat the purpose a bit.

Would appreciate any help.

export default function array(state = {}, action) {
switch (action.type) {
  case "UPDATE_ARRAY":state={
        ...state,
        array:action.array
                   }
    return state;
  default:
    return state;

} }

  • you should always update your state immutably,instead of mutating the current application state ,you should create another object and return that.State should be immutable ,only way to change the state is to create a new one.This helps to improve the performance of the application.
  • I am not sure if you application has more than one reducer or not, if it has, than you must be using combine reducer method .So to access state.array in mapsStateToProps is like this

    const mapStateToProps = (state) => { return {

     messages: state.{reducer_name}.message, array: state.{reducer_name}.array 

    }; };

  • in place of 'reducer_name' you have to specify the reducers_name which you have define in combine reducer

  • And last mapStateToProps return array ,in props not in component state. which you can access in this way {this.props.array},you cant set component state in componentDidMount and in componentWillRecieveProps (in case of aysnc action).

I am not sure the following is your issues, but hope these will help:

export default function array(state = {}, {type, array}) {
    switch (type) {
      case "UPDATE_ARRAY":
        return {...state, array};
      default:
        return state;
  }
}

Your reducer should be pure, which you had is mutating the state.

constructor(props) {
    super(props);
    this.state = {
      array: array // what is array?
    }
}

Above constructor is not right. You should be able to access the array from this.props.array as your mapStateToProps

Do a console.log(this.props) in your render function or ComponentWillReceiveProps , see if you can something :)

Your component will receive array as a field in its props field. Your code assumes it's in the state field. So instead of:

this.state = {
      array: array
    }

you would just access this.props.array wherever in your code you need to use the array. You don't need to put it in the local state at all. Usually, you would use it in the render function, like in this example:

render()
{
  return <div>The array contains {this.props.array.length} items.</div>
}

I wonder if you're confusing local state with the Redux store's state? Local state is what you get/set when you access this.state in your component code. Every component can have its own state object that it can read from and write to.

The Redux store's state is what's passed in to mapStateToProps . It's usually the entire state object of all the combined reducers in your top-level reducer (though if you only have one reducer function and are not using combineReducers , then the store state is identical to that single reducer's state).

I suggest choosing more descriptive variable names, so that your code will be more readable. It's hard to understand what your intentions are for your code with such generic names. For example, you could name your reducer something that indicates what it's for, like bookListReducer , and name the array you want to store and retrieve for what will go inside it, like books . Naming both your reducer and all your variables array makes it harder to read your code. This will help anyone who reads your code in the future - including, most importantly, you!, as well as future Stack Overflow readers of your future questions (and perhaps this one if you edit it).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM