javascript - 组件接收的不是当前值,而是先前的输入值

标签 javascript reactjs redux redux-form

我有两个组件来表示文章列表和过滤表单。每次更改任何表单字段时,我都需要发送一个包含所选过滤器的 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)。

例如:

  1. 我加载页面并选择 draft 选项。 undefined 被打印出来。
  2. 我选择已发布。 { status: 'draft' } 被打印出来。
  3. 我再次选择 draft... { status: 'published' } 被打印出来。

我检查了 redux store 和 componend Prop 。两者都根据表单交互而变化。但是我的函数返回的是之前的值,而不是 onChange 发送的新值。

这显然是我的代码的问题,很可能是我将函数从父组件传递到子组件的方式。

我做错了什么?

最佳答案

你的功能没有问题。我认为正在发生的事情是,当您第一次选择该选项时,您的回调将被触发,并且正在控制台记录 myCustomForm.values current 状态 由 redux-form 更改。所以当选择改变时:

  1. 你的回调被触发了...
  2. ...然后 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/

相关文章:

javascript - 具有无限子类别级别的 Laravel 下拉嵌套类别给出错误

javascript - 返回格式为(x 年、x 月、x 天)的日期 - JavaScript

javascript - 在 Forge Viewer 中第二次之后扩展不会加载

javascript - Web应用程序使用Redux,如何处理逻辑只需要执行一次

javascript setinterval 崩溃资源管理器 11 选项卡

javascript - 我想查看有多少人选择了

javascript - React-Semantic UI 调度事件不起作用

javascript - 获取渲染 React Target/DIV

ReactJS、SocketIO 和 Redux - 什么是正确的设计

reactjs - redux 连接组件如何知道何时重新渲染?