我有两个组件来表示文章列表和过滤表单。每次更改任何表单字段时,我都需要发送一个包含所选过滤器的 HTTP 请求。
我为 SearchForm
编写了以下代码:
import React from 'react';
import { reduxForm, Field } from 'redux-form';
const SearchForm = ({ onFormChange }) => (
<form>
<Field component='select' name='status' onChange={onFormChange}>
<option>All</option>
<option value='published'>Published</option>
<option value='draft'>Draft</option>
</Field>
<Field
component='input'
type='text'
placeholder='Containing'
onChange={onFormChange}
/>
</form>
);
export default reduxForm({ form: 'myCustomForm' })(SearchForm);
以及 PostsList
的以下内容:
import React, { Component } from 'react';
import SearchForm from './SearchForm';
import { dispatch } from 'redux';
class PostsList extends Component {
constructor(props) {
super();
this.onFormChange = this.onFormChange.bind(this);
}
onFormChange() {
// Here I need to make the HTTP Call.
console.info(this.props.myCustomForm.values);
}
componentWillMount() {
this.props.actions.fetchArticles();
}
render() {
return (
<div>
<SearchForm onFormChange={this.onFormChange} />
<ul>
{ this.props.articles.map((article) => (<li>{article.title}</li>)) }
</ul>
</div>
);
}
}
const mapStateToProps = (state) => ({
myCustomForm: state.form.myCustomForm
});
const mapDispatchToProps = (dispatch) => ({
actions: {
fetchArticles: dispatch({ type: 'FETCH_ARTICLES' })
}
});
export default connect(mapStateToProps, mapDispatchToProps)(PostsList);
虽然渲染本身没有任何问题,但是当我更改表单时 myCustomForm.values
属性发生了一些非常糟糕的事情。
当我第一次这样做时,console.log(this.props.myCustomForm.values)
调用返回 undefined
,下一个调用返回上一个值(value)。
例如:
- 我加载页面并选择
draft
选项。undefined
被打印出来。 - 我选择已发布。
{ status: 'draft' }
被打印出来。 - 我再次选择
draft
...{ status: 'published' }
被打印出来。
我检查了 redux store 和 componend Prop 。两者都根据表单交互而变化。但是我的函数返回的是之前的值,而不是 onChange
发送的新值。
这显然是我的代码的问题,很可能是我将函数从父组件传递到子组件的方式。
我做错了什么?
最佳答案
你的功能没有问题。我认为正在发生的事情是,当您第一次选择该选项时,您的回调将被触发,并且正在控制台记录 myCustomForm.values
的 current 状态 由 redux-form 更改。所以当选择改变时:
- 你的回调被触发了...
- ...然后 redux-form 正在更新状态。
所以。当您的回调正在制作 console.log 时,它正在打印尚未更新的商店。
这样做,你会发现这是真的:
onFormChange(e) {
// Here I need to make the HTTP Call.
console.info(e.currentTarget.value);
}
编辑
我的第一个问题是,您真的需要将这个值存储在 redux 中并使用 redux-form
吗?这是一个简单的案例,您可以通过我在上面向您展示的方式获得当前值。
但是,如果不是这种情况,则此处不需要回调,您只需要在连接的组件(PostsList)中检测表单中的值已更改。您可以使用 componentWillReceiveProps
来实现它钩子(Hook)。
class PostsList extends Component {
constructor(props) {
super(props); // you should pass props to parent constructor
this.onFormChange = this.onFormChange.bind(this);
}
componentWillReceiveProps(nextProps) {
if(this.props.myCustomForm.values !== nextProps.myCustomForm.values) {
// do your ajax here....
}
}
componentWillMount(nextProps) {
this.props.actions.fetchArticles();
}
render() {
return (
<div>
<SearchForm />
<ul>
{ this.props.articles.map((article) => (<li>{article.title}</li>)) }
</ul>
</div>
);
}
}
关于javascript - 组件接收的不是当前值,而是先前的输入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47062150/