javascript - 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
解决方案
更新:
目前,_handleInputChange
方法只会修改子组件的状态,子组件会调用getDerivedStateFromProps
.
该方法的工作方式是,当每个newProps或setState调用发生时都会调用它。
因此,行为如下:
- 您使用处理程序更改值。
getDerivedStateFromProps
get 被调用,它将currentLevel
从父组件中获取值,由于我们没有在那里进行任何更改,因此它仍然没有被修改,因此,它将用父组件中存在的值覆盖来自调用处理程序的新值组件,未修改。
为了解决这个问题:我们需要一个来自父组件的回调函数,它的工作与 handleInputChange 相同。
所以:
- 向你的父组件添加一个
handleCurrentLevelChange
方法,它只有一个参数e.target.value
,它的工作是修改currentLevel
你的父状态。 - 将您创建的名称传递
handleCurrentLevelChange
给您的NameEditor您想要的名称,可能是相同的名称。 - 修改你孩子的handlr如下:
_handleInputChange = (e, cb) => {
this.setState({
currentLevel: e.target.value
}, () => {
cb && cb(e.target.value) //this makes the callback optional.
});
}
- 修改您的 onChange 属性以适应新的更新:
<input
placeholder={0}
value={currentLevel}
onChange={(e) => this._handleInputChange(e, handleCurrentLevelChange)}
属性和处理程序的新行为onChange
将允许更改发生在您的孩子和您的父母身上。
这应该可以解决当前的问题。
推荐阅读
- c# - Selenium 与 C# - 某些功能在 Chrome 浏览器版本 90 上不起作用,但对我的队友在他们的机器上运行良好
- python-3.x - 使用循环 python 一次又一次地滚动 Instagram 页面
- javascript - 在不和谐中发送时整数显示不同(discord.js)
- c# - 在 ASP.NET Core Web API Net5.0 中正确使用全局处理异常并允许授权请求
- angular - Angular 单元测试(使用 Getter):错误:没有带有名称的表单控件的值访问器
- laravel-5 - 如何用 VAPID 替换 FCM,我有推送面板,我想将旧的 fcm 功能替换为 vapid
- reactjs - 如何使用 React 从嵌套对象创建列表?
- javascript - v-if in v-for 搞乱了 CSS
- javascript - 如何通过右键菜单将链接传递给javascript函数?
- excel - 将工作表复制到新工作簿脚本实验室