组件接收的不是当前值,而是先前的输入值
Component is not receiving current, but previous input values
我有两个组件来表示文章列表和过滤表单。每次更改任何表单字段时,我都需要发送一个包含 selected 过滤器的 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)
调用 returns undefined
,下一个调用 return 以前的值。
例如:
- 我加载页面和 select
draft
选项。 undefined
被打印出来。
- 我select发表了。
{ status: 'draft' }
被打印出来。
- 我再次select
draft
... { status: 'published' }
被打印出来。
我检查了 redux store 和 componend 道具。两者都根据表单交互而变化。但我的功能是 returning 前一个值,而不是 onChange
.
发送的新值
这显然是我的代码的问题,很可能是我将函数从父组件传递到子组件的方式。
我做错了什么?
你的功能没有问题。我认为正在发生的事情是你第一次 select 你的回调被触发的选项并且是控制台日志 当前 状态 myCustomForm.values
which haven '还没有被 redux-form 改变。所以当 select 改变时:
- 您的回调已触发...
- ...然后 redux-form 正在更新状态。
所以。当您的回调正在 console.log 时,它正在打印尚未更新的商店。
这样做,你会发现它是真的:
onFormChange(e) {
// Here I need to make the HTTP Call.
console.info(e.currentTarget.value);
}
编辑
我的第一个问题是,你真的需要将这个值存储在 redux 中并使用 redux-form
吗?这是一个简单的案例,您可以通过我在上面向您展示的方式获得当前值。
但是,如果不是这种情况,则此处不需要回调,您只需要在连接的组件 (PostsList) 中检测表单中的值已更改。您可以使用 componentWillReceiveProps
钩子实现它。
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>
);
}
}
我有两个组件来表示文章列表和过滤表单。每次更改任何表单字段时,我都需要发送一个包含 selected 过滤器的 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)
调用 returns undefined
,下一个调用 return 以前的值。
例如:
- 我加载页面和 select
draft
选项。undefined
被打印出来。 - 我select发表了。
{ status: 'draft' }
被打印出来。 - 我再次select
draft
...{ status: 'published' }
被打印出来。
我检查了 redux store 和 componend 道具。两者都根据表单交互而变化。但我的功能是 returning 前一个值,而不是 onChange
.
这显然是我的代码的问题,很可能是我将函数从父组件传递到子组件的方式。
我做错了什么?
你的功能没有问题。我认为正在发生的事情是你第一次 select 你的回调被触发的选项并且是控制台日志 当前 状态 myCustomForm.values
which haven '还没有被 redux-form 改变。所以当 select 改变时:
- 您的回调已触发...
- ...然后 redux-form 正在更新状态。
所以。当您的回调正在 console.log 时,它正在打印尚未更新的商店。
这样做,你会发现它是真的:
onFormChange(e) {
// Here I need to make the HTTP Call.
console.info(e.currentTarget.value);
}
编辑
我的第一个问题是,你真的需要将这个值存储在 redux 中并使用 redux-form
吗?这是一个简单的案例,您可以通过我在上面向您展示的方式获得当前值。
但是,如果不是这种情况,则此处不需要回调,您只需要在连接的组件 (PostsList) 中检测表单中的值已更改。您可以使用 componentWillReceiveProps
钩子实现它。
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>
);
}
}