【问题标题】:How can set my state once when listening resize event监听调整大小事件时如何设置我的状态
【发布时间】:2019-09-19 13:22:40
【问题描述】:

在我的react应用中,我需要监听窗口的resize事件,所以如果窗口大小小于X,我会调用mobileFunc,如果大于X,我会调用desktopFunc渲染一些带有很多变量的html . (这些变量和参数对于 desktopFunc 和 mobileFunc 获得不同的值)

我正在监听事件,但是,每个窗口的大小变化都会一次又一次地设置我的状态。我不想那样做。我正在尝试找到一种方法来在必要时设置/更改我的状态,并在可能的情况下减少监听调整大小事件(可选)。我愿意接受有关去抖动、shouldComponentUpdate 等的建议。我应该找到一种有效的方法。

// mobile is false by default in my state.
componentDidMount() {
    window.addEventListener('resize', this.setDeviceType)
}
componentWillUnmount(){
    window.removeEventListener('resize', this.setDeviceType)
}

setDeviceType() {
    if(window.innerWidth < 768) {
        this.setState({mobile: true})
    } else {
        this.setState({mobile: false})
    }
}

render() {
    return(
        <div>
            {this.state.mobile ? this.mobileFunc() : this.desktopFunc()}
        </div>
    )
}

【问题讨论】:

  • 使用debounce
  • 我该怎么做?你能根据我的代码给我一个例子吗?
  • 顺便说一句,这样做的原因是什么?我很少看到真正需要在 JS 中实际使用这样的东西(尽管肯定有用例)。

标签: javascript reactjs addeventlistener debouncing


【解决方案1】:

我还没有测试过,但我认为这可能有效...

// mobile is false by default in my state.
componentDidMount() {
    window.addEventListener('resize', this.setDeviceType)
}
componentWillUnmount(){
    window.removeEventListener('resize', this.setDeviceType)
}

setDeviceType() {
    const { mobile } = this.state;
    if(window.innerWidth < 768) {
        if(!mobile) {
            this.setState({mobile: true})
        }
    } else {
        if(mobile) {
            this.setState({mobile: false})
        }
    }
}

render() {
    const { mobile } = this.state;
    return(
        <div>
            {mobile ? this.mobileFunc() : this.desktopFunc()}
        </div>
    )
}

if/else 块可以清理一些,但如果当前不是你想要的,你真的可以在线执行setState

【讨论】:

  • 这可能会产生奇怪的副作用setState 是异步的,并且 resize 事件触发得非常快,应该使用实例变量来完成
  • 不,我不会使用实例变量(这样做需要forceUpdate 或一些额外的检查)。如果有什么你想像你在原始评论中提到的那样去抖动调整大小事件。或者,您可以使用之前的状态进行一些额外的检查 (this.setState((prevState) =&gt; { ... });)。我可以看到的另一个选项是删除事件侦听器 -> 然后 setState -> 使用 setState 的回调重新启用事件侦听器。所有这些都是即兴的,每个选项(或我没有想到的其他选项)可能都有优点/缺点。
【解决方案2】:

您可以使用去抖动功能。 例如https://lodash.com/docs/#debounce

【讨论】:

    猜你喜欢
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    相关资源
    最近更新 更多