Redux / React:为什么`this.props`未定义

时间:2016-11-21 15:55:26

标签: reactjs redux react-redux

我的代码:

  render() {
    console.log( 'render, state' + Array.isArray(this.props.users) + ',' + JSON.stringify(this.props.users) );
    return (
      <section>
        <div>testing</div>
        <div>{JSON.stringify(this.props.users)}</div>
        <ul>
          {this.props.users.map( user => <li>{user.email}</li>)}
        </ul>
      </section>
    );
  }

<div>testing</div><div>{JSON.stringify(this.props.users)}</div>都可以正常工作(删除<ul>...</ul>后)。但是<ul>...</ul>没有用。错误是:

Uncaught TypeError: Cannot read property 'map' of undefined

欢迎任何评论。感谢

更新

以下代码工作正常,this.props.users是一个数组,所有控制台日志看起来都不错。 我只需要知道<ul>{this.props.users.map( user => <li>{user.email}</li>)}</ul>无效的原因。为什么this.props.users中的<ul>...</ul>未定义。

  render() {
    console.log( 'render, state' + Array.isArray(this.props.users) + ',' + JSON.stringify(this.props.users) );
    return (
      <section>
        <div>testing</div>
        <div>{JSON.stringify(this.props.users)}</div>
      </section>
    );
  }

上述代码的控制台输出(仅两秒):

render, statetrue,[{"_id":"5831e6df511e","updatedAt":"removed","createdAt":"removed","email":"removed","password":"xxxx","__v":0,"role":"xxx","profile":{"firstName":"test","lastName":"tester"}},{...}, {...}]

更新

我的代码:

import { connect } from 'react-redux';
import { fetchAllUsers } from '../../actions/index';

class HomePage extends Component {
  componentWillMount() {
    console.log( 'componentWillMount()' );
    this.props.fetchAllUsers();
  }

  render() {
    console.log( 'render(), ' + Array.isArray(this.props.users) + ',' + JSON.stringify(this.props.users) );
    return (
      <section>
        <div>{JSON.stringify(this.props.users)}</div>
      </section>
    );
  }
}

function mapStateToProps(state) {
    console.log( 'state:' + JSON.stringify(state) );// working fine, and the console.log is OK. not added to this post
    return  {
        users: state.admin.users
    }
}

export default connect(mapStateToProps, {fetchAllUsers})(HomePage);

console.log(删除了User对象中的一些细节。):

render(), true,[{"_id":"5831","profile":{"firstName":"test","lastName":"tester"}},{"_id":"5831e874cedf511f", "profile":{"firstName":"cccc","lastName":"cc"}},{"_id":"5831120","profile":{"firstName":"cccccccc","lastName":"ccc"}}]

并且,在网页上显示了this.props.users字符串。

我的问题是为什么<ul>{this.props.users.map( user => <li>{user.email}</li>)}</ul>无效,但<div>{JSON.stringify(this.props.users)}</div>工作正常。

我想我已经清楚地描述了我的问题。如果需要更多信息,请告诉我。

更多详情

我的admin_reducer.js

import { FETCH_ALL_USERS } from '../actions/types';

const INITIAL_STATE = { users:[] };

export default function (state = INITIAL_STATE, action) {
  console.log( 'users is action.payload:'+JSON.stringify( { users:action.payload } ) );
  return Object.assign( {}, state, {users:action.payload});
  //return { ...state, users:action.payload };
}

我的index.js

import adminReducer from './admin_reducer';

const rootReducer = combineReducers({
  ...
  admin: adminReducer
});

导出默认的rootReducer;

my action.js
export function fetchAllUsers() {
  return function(dispatch) {
    axios.get(`${API_URL}/user/all`)
    .then(response => {
      dispatch({
        type: FETCH_ALL_USERS,
        payload: response.data
      });
    })
    .catch(response => dispatch(errorHandler(response.data.error)))
  }
}

更新

为什么console.log(this.props.users)的控制台日志是[object Object],[object Object],[object Object]

2 个答案:

答案 0 :(得分:1)

首先,根据react docs,异步请求应该在componentDidMount方法中进行。

其次,要确保您没有尝试map未初始化的数组,请使用:

<ul>{(this.props.users || []).map( user => <li>{user.someProperty}</li> )}</ul>

如果由于某种原因忘记初始化数组,这应该包含它。

答案 1 :(得分:0)

你可以毫无错误地调用它。

JSON.stringify(this.props.users)

...因为它只是输出&#34; undefined&#34;)。这是有效的。但是,如果您尝试调用返回的未定义上的方法,当然会失败...

// Following tries to call undefined.map(), which is of course wrong
this.props.users.map( user => <li>{user.email}</li>)

解决您的场景的常用简写使用&#34;短路运算符&#34; (像一个快速的&#34;如果(是真的)&#34;)......

<ul>{this.props.user && this.props.users.map( user => <li>{user.email}</li>)}</ul>

^^注意&#34; this.props.user&amp;&amp; &#34;,如果this.props.user为null或未定义,则阻止调用以下this.props.user.map()