首页 文章

以redux形式从状态加载初始值

提问于
浏览
1

我正在尝试在Redux表单中加载初始值(我从异步调用到服务器),但没有任何反应 . 服务器调用工作正常(我可以看到我的redux状态更新),但表单不显示值 .

我阅读了有关堆栈溢出的所有问题,并应用了所有解决方案,但没有任何效果:

我通过connect函数传递initialValues(通过异步调用的初始值更新),并将enableReinitialize:true添加到reduxForm()

我的代码如下 . 我没有显示动作也没有减速器,因为我认为它们工作正常(我将它们用于其他没有问题的视图) .

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom'
import { reduxForm, Field } from 'redux-form';

import { BASEURL } from '../config'

import { updateBenefit, fetchBenefit } from '../actions';


class SubsidyTiming extends Component {

  componentWillMount() {
    this.props.fetchBenefit(this.props.match.params.benefit)
  }

  renderField(field) {
    return (
      <div className="form-group">
        <label>{field.label}</label>
        <input
          className="form-control"
          type={field.type}
          {...field.input}/>
      </div>
    )
  }

  renderSelect(field) {
    return (
      <div className="form-group">
        <label>{field.label}</label>
        <select
          className="form-control"
          {...field.input}>
            {field.children}
        </select>
      </div>
    )
  }

  onSubmit = (values) => {
  this.props.updateBenefit(values, this.props.match.params.benefit, (subsidy_name) => {
    this.props.history.push(`${BASEURL}/benefits`)
  }); }


  render() {
    if (!this.props.initialValues) {
      return (<h1>{I18n.t("loading")}</h1>)
    }

    return (
      <div>
        <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
          <Field
            label={I18n.t("benefits.new.start.subsidy")}
            name="opening_date"
            type="date"
            component={this.renderField}
          />
          <Field
            label={I18n.t("benefits.new.end.subsidy")}
            name="closing_date"
            type="date"
            component={this.renderField}
          />
          <Field
            label={I18n.t("benefits.new.is_renewable.subsidy")}
            name="is_renewable"
            type="checkbox"
            component={this.renderField}
          />
          <Field
            label={I18n.t("benefits.new.frequency.subsidy")}
            name="frequency"
            type="select"
            component={this.renderSelect}
          >
            <option></option>
            <option value="weekly">{I18n.t("frequency.weekly")}</option>
            <option value="monthly">{I18n.t("frequency.monthly")}</option>
            <option value="quarterly">{I18n.t("frequency.quarterly")}</option>
            <option value="semiannually">{I18n.t("frequency.semiannually")}</option>
            <option value="annually">{I18n.t("frequency.annually")}</option>
          </Field>
          <button
            className="btn btn-primary"
            type="submit"
            disabled={this.props.pristine || this.props.submitting}>
            Sauver et continuer
          </button>
        </form>

      </div>
    )
  }

}

function mapStateToProps(state, ownProps) {
  return {
    initialValues: state.benefit
  }
}

export default reduxForm({ form: 'updateSubsidyForm', enableReinitialize: true })(
  connect(mapStateToProps, { updateBenefit, fetchBenefit })(SubsidyTiming)
);

谢谢你的帮助 !


EDIT

这是我的action.js文件:

import { APIENDPOINT } from '../config'

export const FETCH_BENEFIT = 'FETCH_BENEFIT'


const csrfToken = document.querySelector('meta[name="csrf-token"]').attributes.content.value;


export function fetchBenefit(benefit) {
  const url = `${APIENDPOINT}/${benefit}`
  const promise = fetch(url, { credentials: 'same-origin' }).then(r => r.json())

  return {
    type: FETCH_BENEFIT,
    payload: promise
  }
}

export function updateBenefit(body, name, callback) {
  const promise = fetch(`${APIENDPOINT}/${name}`, {
    method: 'PUT',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken
    },
    credentials: 'same-origin',
    body: JSON.stringify(body)
  }).then(r => r.json())
    .then(r => callback(r.name))

  return {
    type: BENEFIT_UPDATED,
    payload: promise
  }
}

还有我的benefit_reducer.js文件

import { FETCH_BENEFIT } from '../actions';

export default function(state = null, action) {
  switch (action.type) {
    case FETCH_BENEFIT: {
      return action.payload
    }
    default:
      return state;
  }
}

1 回答

  • 0

    除非你告诉它,你的组件不会在道具更改时重新渲染(你的Redux状态将在你的组件的道具中) . 一种方法是首先将数据设置为 null 状态,在 componentWillMount() 中获取它,使用 getDerivedStateFromProps() ,然后从状态渲染它 .

    static getDerivedStateFromProps(props, state) {
      if (props.intialValues !== state.initialValues) {
        return { ...state, initialValues };
      }     
    
      return null;
    }
    

相关问题