Reactjs “反应”;“忘记”;使用去盎司函数时的状态
对于比我更了解React/RN的人来说,这是一个问题。当我将可触摸组件(即按钮)包装在带有去盎司功能的轻量级包装中(以防止调用onPress处理程序过快),它通常会按预期工作。然而,在一系列非常特殊的情况下,事情会出错。如果我将父组件的状态向下传递到按钮的onPress属性中,如果我正在访问的状态属性已在render方法中被分解,然后作为此变量传递,而不是简单地作为this.state.foo访问,则onPress处理程序会将其读取为其初始状态值,即使它已被更新。这可能令人困惑,因此请允许我向您展示一个快速、不完整的示例:Reactjs “反应”;“忘记”;使用去盎司函数时的状态,reactjs,react-native,Reactjs,React Native,对于比我更了解React/RN的人来说,这是一个问题。当我将可触摸组件(即按钮)包装在带有去盎司功能的轻量级包装中(以防止调用onPress处理程序过快),它通常会按预期工作。然而,在一系列非常特殊的情况下,事情会出错。如果我将父组件的状态向下传递到按钮的onPress属性中,如果我正在访问的状态属性已在render方法中被分解,然后作为此变量传递,而不是简单地作为this.state.foo访问,则onPress处理程序会将其读取为其初始状态值,即使它已被更新。这可能令人困惑,因此请允许我向您
class DebounceButton extends Component {
handlePress = debounce(this.props.onPress, 500)
render() {
return (
<Button onPress={this.handlePress}
)
}
}
class Screen extends Component {
state = {
foo: 0
}
render() {
const { foo } = this.state
return (
<Button onPress={() => {this.setState({ foo: this.state.foo + 1 })}}/>
<DebounceButton onPress={() => {console.log(foo)}}/>
<DebounceButton onPress={() => {console.log(this.state.foo)}}/>
)
}
}
class DebounceButton扩展组件{
扶手压力=脱盎司(this.props.onPress,500)
render(){
返回(
{console.log(foo)}}/>
{console.log(this.state.foo)}/>
)
}
}
如果我按下按钮,foo将增加到1。然后,如果我按下第一个去抖动按钮,控制台将记录0。如果我按第二个键,它将按应有的方式记录1。请注意,仅当状态通过debounce函数传递并指定给render方法中的变量时,才会发生这种情况。这就好像React“忘记”了当前状态,并默认为其初始值。这对我来说不再是一个bug,因为我不再使用这种去盎司范式了,但我很想更好地理解它,以便更好地掌握React的工作方式。非常感谢您的任何见解
类属性handlePress=debounce(this.props.onPress,500)
仅在首次创建DebounceButton
时才进行计算,因此在首次渲染后更改onPress
是无效的
您可以创建一个新函数,在其中调用this.props.onPress
。这样每次都将使用This.props.onPress
的当前值
class DebounceButton扩展组件{
手压=脱盎司(()=>{
this.props.onPress();
}, 500);
render(){
返回;
}
}
setState有一个可以访问prevState和newState的更新程序。利用类似于此答案的功能可能会有所帮助。这很有效,谢谢!那么,为什么我以前的方法在传入this.state.foo时有效,而不是以前的解构foo?是否因为React正在侦听状态中的更改并将其应用于引用this.state的所有位置?既然foo已经被解构,这种情况就不再发生了,因为它不再与状态绑定?@kevbot,不客气()=>{console.log(foo)}
最初是()=>{console.log(0)}
,因为创建该函数时foo
是0
,并且在DebounceButton
中从未更改,因为它只使用初始函数()=>{console.log(this.state.foo)}
在调用它时计算this.state.foo
并因此获得正确的值,与我的答案中的handlePress
的实现方式相同。