使用去抖功能时反应“忘记”状态

时间:2018-11-01 20:08:07

标签: 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)}}/>
        )
    }
}

如果按Button,则foo会递增为1。如果再按第一个DebounceButton,则控制台将记录为0。如果按第二个,它将按应记录为1。请注意,仅当状态通过去抖动功能传递并在render方法中分配给变量时,才会发生这种情况。就像React正在“忘记”当前状态是什么一样,并且默认为其初始值。对我而言,这不再是一个错误,因为我不再使用这种去抖动范式了,但是我很好奇地了解它,因此我可以更好地了解React的工作方式。非常感谢任何见解。

1 个答案:

答案 0 :(得分:2)

类属性handlePress = debounce(this.props.onPress, 500)仅在首次创建DebounceButton时进行评估,因此在onPress首次呈现后对其进行更改是不可行的。

您可以创建一个新函数来调用其中的this.props.onPress。这样,每次都会使用this.props.onPress的当前值。

class DebounceButton extends Component {
    handlePress = debounce(() => {
        this.props.onPress();
    }, 500);

    render() {
        return <Button onPress={this.handlePress} />;
    }
}