以冗余形式从状态加载初始值



我试图在Redux表单中加载初始值(从对服务器的异步调用中获得(,但什么也没发生。服务器调用运行良好(我可以看到我的redux状态正在更新(,但表单没有显示值。

我阅读了所有关于堆栈溢出的问题,并应用了所有的解决方案,但都不起作用:

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

我的代码在下面。我没有展示动作或减速器,因为我相信它们运行良好(我将它们用于其他没有问题的视图(。

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)
);

谢谢你的帮助!


编辑

这是我的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;
}
}

除非你告诉它,否则你的组件不会在props更改时重新渲染(你的Redux状态将在组件的props中(。一种方法是最初将数据作为null在状态中,在componentWillMount()中获取数据,使用getDerivedStateFromProps(),然后从状态中渲染。

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

最新更新