javascript - React,调用一个无状态函数来组织代码,但是这个怎么绑定呢?
问题描述
鉴于此反应代码
<form onSubmit={this.onSubmit}>
执行功能
import {onFormSubmit} from '../onFormSubmit'
.....
onSubmit = (e) => {
// here I have access to "this" thanks to the arrow functions
e.preventDefault()
onFormSubmit(this.state.files, this.props)
}
作为无状态函数驻留在onFormSubmit
另一个文件中的位置
export const onFormSubmit = async (files,props) => {
this.setState(... // error
}
当我在 onFormSubmit 函数中时,我看到我丢失了“this”,因此我无法执行例如this.setState
那么,我怎样才能保持对这个的访问呢?
如答案中所述,选项 A是忘记箭头:
onSubmit = (e) => {
// here I have access to "this" thanks to the arrow functions
e.preventDefault()
onFormSubmit.bind(this)(this.state.files, this.props)
}
.
export async onFormSubmit = function(files,props) {
this.setState(... // now it works
}
选项 Bthis
,作为变量传递
onSubmit = (e) => {
// here I have access to "this" thanks to the arrow functions
e.preventDefault()
let self = this
onFormSubmit(self)
}
选项 C,重新定义onFormSubmit
为更新程序,如答案中所述,但此处不是选项,因为该函数不仅更新状态,例如:
export const onFormSubmit = async (files,props) => {
if (files) {
... upload file ... parse file ...
this.setState({'data': data})
} else {
... fetch file ... concat file ... doesn't update the state
}
... and more calculations
this.setState({...})
}
解决方案
onFormSubmit
是一个箭头函数,它不能被绑定,除非它被转译为 ES5,并且依赖它会是一个错误。
一个快速而肮脏的解决方法是使其成为常规功能:
export async function onFormSubmit (files,props) {
this.setState(...
}
在这种情况下依赖动态可能会很尴尬this
,在这一点上,它并不比this
作为参数传递更好。
由于此函数的目的是更新状态,因此更简洁的方法是使其成为状态更新器工厂:
export const onFormSubmit = (props) => prevState => {
const { files } = prevState;
return { /* new state */ };
}
可以像这样使用:
this.setState(onFormSubmit(this.props));
files
上可用prevState
。this.state
与 with 一起使用是setState
一种反模式,因为setState
它是异步的,这可能会导致竞争条件。
或者让它不负责更新状态,如果它是异步的,例如它返回一个承诺:
const newStateObj = await onFormSubmit(this.state.files, this.props);
this.setState(newStateObj);
如果它是同步的,this.state
由于上面提到的原因,使用不会是一个好主意。
推荐阅读
- node.js - 更新纱线后,由于节点模块相关的导入错误,反应应用程序无法编译
- python - 大熊猫的最大值和总和
- javascript - React 错误边界被调用但不渲染
- java - Spring JDBC 模板 - java.sql.SQLRecoverableException: Closed Statement: next
- python-3.x - 如何使自定义数据类可下标
- android - 离子cordova在使用MediaCapture时构建android问题
- python - 如何在pygame的每个Tile网格中绘制数字?
- c# - 具有 Entity Framework Core 的 .NET 控制台应用程序:“进程没有包标识”仅在没有调试的情况下启动
- react-native - undefined 不是对象(评估“expoModule.Components.BlurView”)
- java - 在 Can Foundry PCF 中 manifest.yml 的 JAVA_OPTS 中配置 keystore