【发布时间】:2018-12-18 00:33:49
【问题描述】:
我试图稍微干掉我的反应表单,所以我想将我的基本输入处理功能移动到一个实用程序模块并尝试重用它。这个想法是更新一个表示状态的对象,在 Promise 中返回它,然后在本地快速更新状态。
组件
import handleInputChange from "./utility"
class MyInputComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: {
title: ""
}
};
}
render() {
return (
<input
type="text"
id="title"
value={this.state.data.title}
onChange={e => handleInputChange(e, this.state).then(res => {
this.setState(res);
})}
/>
)
}
};
utility.js
export const handleInputChange = (event, state) => {
const { id, value } = event.target;
return Promise.resolve({
data: {
...state.data,
[id]: value
}
});
};
它似乎工作正常,但问题是输入的光标总是跳到输入的末尾。
如果我使用普通的本地输入处理程序并且忽略 DRY,那么它可以正常工作。 例如,这对光标没有问题:
组件
class MyInputComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: {
title: ""
}
};
}
handleInputChange = event => {
const { id, value } = event.target;
this.setState({
data: {
...this.state.data,
[id]: value
}
});
};
render() {
return (
<input
type="text"
id="title"
value={this.state.data.title}
onChange={this.handleInputChange}
/>
)
}
};
知道为什么当我尝试 DRY 时会出现光标问题吗?承诺是否延迟渲染,因此光标不知道去哪里?感谢您的帮助。
【问题讨论】:
-
两者的区别在于
Promise中的setState会在当前执行帧通过调度一个(micro)task完成之后发生。在controlled components的情况下,这似乎改变了浏览器的行为。我没有真正看到您的handleInput函数的价值,但您仍然可以使用函数组合并保持同步:handle = (state, cb) => (event) => (event.preventDefault(); cb({state, event.target })(这可能是onSubmit道具的处理程序)。
标签: javascript reactjs dry