首页 > 解决方案 > React 16.4 - 手动表单输入填充以及来自 getDerivedStateFromProps 的更新?

问题描述

一旦更新React 16.4getDerivedStateFromProps ,我就会遇到一个问题,我们在逻辑上有一些重大变化。现在,它会在传入自己组件的 props 上的每个组件更新时触发。

所以,我已经阅读了文档和手册,但仍然无法弄清楚表单输入字段应该基于传入的道具(controlled component)并且同时能够通过用户自己的输入进行修改的情况?

我也试过这篇文章,但它只涵盖了一次性更新的案例,而不是手动输入案例:Why getDerivedStateFromProps is called after setState?

这是我要重现的小代码:

import PropTypes from 'prop-types'
import React from 'react'

export class NameEditor extends React.Component {
  static propTypes = {
    currentLevel: PropTypes.number
  }

  static defaultProps = {
    currentLevel: 0
  }

  constructor(props) {
    super(props)

    this.state = {
      currentLevel: 0
    }
  }

  static getDerivedStateFromProps(nextProps) {
    return {
      currentLevel: nextProps.currentLevel
    }
  }

  _handleInputChange = e => {
    this.setState({
      currentLevel: e.target.value
    })
  }

  render() {
    const { currentLevel } = this.state

    return (
        <input
          placeholder={0}
          value={currentLevel}
          onChange={this._handleInputChange}
        />
    )
  }
}

export default NameEditor

标签: javascriptreactjsgetderivedstatefromprops

解决方案


更新:

目前,_handleInputChange方法只会修改子组件的状态,子组件会调用getDerivedStateFromProps.

该方法的工作方式是,当每个newPropssetState调用发生时都会调用它。

因此,行为如下:

  1. 您使用处理程序更改值。
  2. getDerivedStateFromPropsget 被调用,它将currentLevel从父组件中获取值,由于我们没有在那里进行任何更改,因此它仍然没有被修改,因此,它将用父组件中存在的值覆盖来自调用处理程序的新值组件,未修改。

为了解决这个问题:我们需要一个来自父组件的回调函数,它的工作与 handleInputChange 相同。

所以:

  1. 向你的父组件添加一个handleCurrentLevelChange方法,它只有一个参数e.target.value,它的工作是修改currentLevel你的状态。
  2. 将您创建的名称传递handleCurrentLevelChange给您的NameEditor您想要的名称,可能是相同的名称。
  3. 修改你孩子的handlr如下:
  _handleInputChange = (e, cb) => {
    this.setState({
      currentLevel: e.target.value
    }, () => {
      cb && cb(e.target.value) //this makes the callback optional.
    });
  }
  1. 修改您的 onChange 属性以适应新的更新:
        <input
          placeholder={0}
          value={currentLevel}
          onChange={(e) => this._handleInputChange(e, handleCurrentLevelChange)}

属性和处理程序的新行为onChange将允许更改发生在您的孩子和您的父母身上。

这应该可以解决当前的问题。


推荐阅读