收听调整大小事件时,如何设置一次状态

时间:2019-04-30 20:43:36

标签: javascript reactjs addeventlistener debouncing

在我的react应用程序中,我需要监听窗口的调整大小事件,因此,如果窗口大小小于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>
    )
}

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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,那么您真的可以在线执行一个import React, { Component } from "react"; // import ReactDOM from "react-dom"; import HTML5Backend from "react-dnd-html5-backend"; import { DragDropContext as dragDropContext } from "react-dnd"; import DragBox from "./DragBox"; import DropBox from "./DropBox"; class MainContext extends Component { render() { return ( <div style={{ borderStyle: "solid" }}> <p style={{ padding: "0px 10px" }}>Main Context</p> <DragBox /> <DropBox /> </div> ); } } module.exports = dragDropContext(HTML5Backend)(MainContext);