状态更改后未调用React \ Redux render()

时间:2018-09-21 14:40:01

标签: javascript reactjs react-redux

我正在尝试从React / Redux项目的服务器中填充一个下拉列表。下拉列表定义为组件,并嵌入到父组件中。

父组件:

import React from 'react';
import Form from 'components/Form';
import { reduxForm } from 'redux-form';
import { Input } from 'components';
import FirstFormList from '../FirstFormList/FirstFormList.js';
import { firstform } from 'redux/modules/firstForm';

class FirstForm extends Form {
  render() {
    const {
      fields: { dateTime }
    } = this.props;
    return (
      <form onSubmit={this.handleApiSubmit(firstform)} className="form-horizontal">
        {this.renderGlobalErrorList()}
        <Input field={dateTime} label="Time Stamp" />
        <div className="form-group">
          <div className="col-md-1" />
          <label htmlFor="select1" className="col-md-1">Select Option</label>
          <div className="col-md-10">
            <FirstFormList />
          </div>
        </div>
        <div className="form-group">
          <div className="col-md-offset-2 col-md-10">
            <button type="submit" className="btn btn-default">Submit</button>
          </div>
        </div>
      </form>
    );
  }
}

FirstForm = reduxForm({
  form: 'firstform',
  fields: ['dateTime']
}
)(FirstForm);

export default FirstForm;

子组件FirstFormList

import React from 'react';
import { connect } from 'react-redux';
import { fetchfirstformlist } from 'redux/modules/firstFormList';

class FirstFormList extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }

  componentDidMount() {
    this.props.fetchfirstformlist();
  }

  render() {
    let optionItems = [];
    if (this.props.items !== undefined && this.props.items !== null) {
      const items = this.props.items;
      optionItems = items.map((item) =>
        <option key={item.value}>{item.label}</option>
      );
    }
    return (
      <div>
        <select className="form-control">
          {optionItems}
        </select>
      </div>
    );
  }
}

export default connect(
  state => ({ items: state.items }),
  { fetchfirstformlist })(FirstFormList);

子组件简化器:

export const FIRSTFORMLISTFETCH_START = 'react/firstform/FIRSTFORMGETLIST_START';
export const FIRSTFORMLISTFETCH_COMPLETE = 'react/firstform/FIRSTFORMGETLIST_COMPLETE';
export const FIRSTFORMLISTFETCH_ERROR = 'react/firstform/FIRSTFORMGETLIST_ERROR';

const initialState = {
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case FIRSTFORMLISTFETCH_COMPLETE:
      return {
        ...state,
        items: action.result.items
      };
    default:
      return state;
  }
}

export function fetchfirstformlist() {
  return {
    types: [FIRSTFORMLISTFETCH_START, FIRSTFORMLISTFETCH_COMPLETE, FIRSTFORMLISTFETCH_ERROR],
    promise: (client) => client.post('/api/firstform/getfirstformlist')
  };
}

如果我在FirstFormList组件中设置了一个断点,则componentDidMount火灾后可以看到服务器返回的项目状态:

export default connect(
  state => ({ items: state.items }),
  { fetchfirstformlist })(FirstFormList);

但是,将项目附加到状态后,组件的render()不会触发。

2 个答案:

答案 0 :(得分:1)

好的,export default connect(state => ({ items: state.items }),{ fetchfirstformlist})(FirstFormList);

中的状态

是还原器状态,不是React状态。因此,您可以删除this.state = {items: []};,因为您不在渲染中使用this.state.items。 您是从this.props.items connect获得state.items的。

其次,您是否正在检查日志以查看减速器中是否有错误。 (我猜如果action.resultundefined,它将在action.result.items上引发错误)。因此,在尝试使用action.result.items之前,您可以检查action.result是否未定义还是为其指定默认值吗?您还应该尝试将带有诺言的行注释掉,看看它是否有效。具有多种类型的行看起来也很可疑。 另外,您可以尝试将花括号添加到一个衬里匿名方法中,并添加其他日志记录和显式返回值。

此外,对生命周期工作做出反应的方式是,仅在组件首次呈现时将构造函数称为 ,然后仅在第一次组件时将componentDidMount也称为 渲染。

第三,为什么不在渲染方法和reducer中使用redux plugin{console.log("test", this.props)}调试redux的状态。这样一来,您肯定会发现错误的出处,因为所提供的信息可能不够。

如果这3个步骤不能解决您的问题或无法帮助您解决问题,请留下评论,我会为您提供帮助。

答案 1 :(得分:0)

我发现了问题。列表项以state.firstFormList.items而不是state.items的状态存储。导出应为:

export default connect(
  state => ({ items: state.firstFormList.items }),
  { fetchfirstformlist })(FirstFormList);

不是

 export default connect(
      state => ({ items: state.items }),
      { fetchfirstformlist })(FirstFormList);