为什么在使用 redux 和 react.js 时我的道具“未定义"? [英] Why are my props `undefined` when using redux and react.js?

查看:22
本文介绍了为什么在使用 redux 和 react.js 时我的道具“未定义"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试向我的应用程序添加一个状态,该状态在某个事件过去时刚刚保存了一个布尔值.我不知道我在这里做错了什么.

减速器:

import * as actionTypes from '../constants/action-types.js';const 初始状态 = [{事件通过:false}];导出默认函数 eventPassed(state = initialState, action) {开关(动作.类型){案例 actionTypes.EVENT_PASSED:返回真;默认:返回状态;}}

行动:

import * as actionTypes from '../constants/action-types';导出函数 eventPassed(eventPassed) {返回 {类型:actionTypes.EVENT_PASSED,有效载荷:{ eventPassed: eventPassed }};}

组件周围的容器:

import React, { Component } from 'react';从'react-redux'导入{连接};从redux"导入 { bindActionCreators };从'../components/example.jsx'导入示例;从 '../actions/app-actions' 导入 { eventPassed };类 ExampleContainer 扩展组件 {使成为() {返回 (<示例 {...this.props}/>);}}const mapDispatchToProps = (dispatch) =>({动作:bindActionCreators({事件通过}, 派遣)});const mapStateToProps = (状态) =>({事件通过:state.eventPassed});导出默认连接(mapStateToProps,mapDispatchToProps)(ExampleContainer);

组件:

import React, { Component, PropTypes } from 'react';类示例扩展组件{构造函数(){极好的();this.action = this.action.bind(this);}componentDidMount() {this.props.actions.eventPassed(true);}行动() {console.log(this.props.eventPassed);}使成为() {返回 (<div><button onClick={this.action}>Action</button>

);}}导出默认示例;

当我尝试在 <Example/> 组件中记录 "this.props.eventPassed" 时,它给了我<强>未定义".有什么遗漏吗?这似乎是 redux 中 store 最简单的用法了.

解决方案

为什么 this.props.eventPassed 被记录为未定义"?:

您此时尝试访问的操作函数 (eventPassed) 在 this.props.actions.eventPassed 中不存在.它实际上只存在于this.props.actions.

这是因为您将操作方法​​绑定到值actions"在您的 mapDispatchToProps 中.这反过来提供了访问eventPassed 动作通过 this.props.actions.

由于 this.props.actions 指向 eventPassed,通过尝试访问this.props.actions.eventPassed 您正在尝试访问该属性操作 eventPassed 上的eventPassed".结果是当您登录此属性,您会收到未定义"

<小时>

其他必要的修改:

mapDispatchToProps 需要返回一个值

一个带有块体的箭头函数不会自动返回值,因此必须定义一个值.所以你的函数需要看起来像:

mapDispatchToProps = (dispatch) =>{返回 { 动作:bindActionCreators(eventPassed, dispatch) }}

<小时>

初始状态是一个包含对象的数组:

const initialState = [{事件通过:false}];

由于您稍后尝试将其引用为 object { eventPassed: true} 而不是对象数组 [ { eventPassed: true } ] 它应该是:

const initialState = {事件通过:false};

<小时>

reducer 需要传回正确的更新(但未突变)状态:

导出默认函数 eventPassed(state = initialState, action) {开关(动作.类型){案例 actionTypes.EVENT_PASSED:返回 {...状态,事件通过:action.payload};默认:返回状态;}}

您最初所做的是返回一个不再是对象(或在原始情况下是对象数组)而只是 true

的值的状态

I tried to add a state to my application that just saved a boolean when some event has passed. I can't figure out what I'm doing wrong here.

Reducer:

import * as actionTypes from '../constants/action-types.js';

const initialState = [{
  eventPassed: false
}];

export default function eventPassed(state = initialState, action) {
  switch (action.type) {
    case actionTypes.EVENT_PASSED:
      return true;
    default:
      return state;
  }
}

Action:

import * as actionTypes from '../constants/action-types';

export function eventPassed(eventPassed) {
  return {
    type: actionTypes.EVENT_PASSED,
    payload: { eventPassed: eventPassed }
  };
}

Container around component:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Example from '../components/example.jsx';
import { eventPassed } from '../actions/app-actions';

class ExampleContainer extends Component {
  render() {
    return (
      <Example {...this.props} />
    );
  }
}

const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators({
    eventPassed
  }, dispatch)
});

const mapStateToProps = (state) => ({
  eventPassed: state.eventPassed
});

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

Component:

import React, { Component, PropTypes } from 'react';

class Example extends Component {

  constructor() {
    super();
    this.action = this.action.bind(this);
  }

  componentDidMount() {
    this.props.actions.eventPassed(true);
  }

  action() {
    console.log(this.props.eventPassed);
  }

  render() {
    return (
      <div>
        <button onClick={this.action}>Action</button>
      </div>
    );
  }
}

export default Example;

When I try to log "this.props.eventPassed" in the <Example /> component it gives me "undefined". Is there something missing? This seems to be the most simple use of the store in redux.

解决方案

Why is this.props.eventPassed logged as "undefined"?:

The action function (eventPassed) you are trying to access at this point does not exist at this.props.actions.eventPassed. It actually exists solely on this.props.actions.

This is because you bound the action method to the value 'actions' in your mapDispatchToProps. This is turn provides gives access to the eventPassed action via this.props.actions.

Since this.props.actions points to eventPassed, by trying to access this.props.actions.eventPassed you are trying to access the property of 'eventPassed' on the action eventPassed. The result is that when you log for this property you receive "undefined"


Other necessary amendments:

mapDispatchToProps needs to return a value

An arrow function with a block body does not automatically return a value and therefore one must be defined. So your function needs to look like:

mapDispatchToProps = (dispatch) => {
  return { actions: bindActionCreators(eventPassed, dispatch) }
} 


Initial state is an array containing an object:

const initialState = [{
  eventPassed: false
}];

Since you're trying to reference it later as an object { eventPassed: true} and not an array of objects [ { eventPassed: true } ] it should be:

const initialState = {
  eventPassed: false
};


The reducer needs to pass back the correct updated (but unmutated) state:

export default function eventPassed(state = initialState, action) {
  switch (action.type) {
    case actionTypes.EVENT_PASSED:
      return {
        ...state,
        eventPassed: action.payload
      };
    default:
      return state;
  }
}

What you were initially doing was returning a state that was no longer an object (or in the original case an array of object) but just the value of true

这篇关于为什么在使用 redux 和 react.js 时我的道具“未定义"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆