【问题标题】:How to setState by user's keyboard input in React?如何在 React 中通过用户的键盘输入设置状态?
【发布时间】:2021-03-05 00:51:46
【问题描述】:

我目前正在写一个2048游戏,它检测用户的键盘输入,然后改变相应方向的状态;但我未能改变状态。我将其用作捕获输入命令的参考。 React onKeyDown/onKeyUp events on non-input elements 然后设置一个名为 keyValue 的字符串来存储键盘输入的字符串值并在我的 addEventListener 中更新 keyValue。但我未能通过我的 componentDidMount 中的 keyValue 设置状态。我的代码如下。我之前也尝试在我的 addEventListner 中设置状态,但它也失败了。有人可以帮忙吗?谢谢。

constructor(props) {
        super(props);
        this.state = {
            board: Array(4).fill().map(x => Array(4).fill(0)),
            score: 0,
            end: false,
            emptySpace: true,
            left: false,
            right: false,
            up: false,
            down: false
        };
    }

   componentDidMount() {
        var cmdDown = false;
        var keyValue = "";
        document.body.addEventListener('keydown', function (event) {
            var key = event.keyCode || event.charCode || 0;
            if ([37, 38, 39, 40].indexOf(key) !== -1) {
                cmdDown = true;
                if ([37].indexOf(key) !== -1) {
                    keyValue = "ArrowLeft";
                } else if ([38].indexOf(key) !== -1) {
                    keyValue = "ArrowUp";
                } else if ([39].indexOf(key) !== -1) {
                    keyValue = "ArrowRight";
                } else if ([40].indexOf(key) !== 1) {
                    keyValue = "ArrowDown"
                }
            }
            console.log(keyValue);
            console.log('CMD DOWN: ' + cmdDown.toString());
        });

        document.body.addEventListener('keyup', function (event) {
            var key = event.keyCode || event.charCode || 0;
            if ([37, 38, 39, 40].indexOf(key) !== -1) {
                cmdDown = false;
            }
            console.log('CMD DOWN: ' + cmdDown.toString());
        });
        if (keyValue === "ArrowUp") {
            this.setState({ up: true });
            this.setState({ down: false });
            this.setState({ left: false });
            this.setState({ right: false });
        } else if (keyValue === "ArrowDown") {
            this.setState({ up: false });
            this.setState({ down: true });
            this.setState({ left: false });
            this.setState({ right: false });
        } else if (keyValue === "ArrowLeft") {
            this.setState({ up: false });
            this.setState({ down: false });
            this.setState({ left: true });
            this.setState({ right: false });
        } else if (keyValue === "ArrowRight") {
            this.setState({ up: false });
            this.setState({ down: false });
            this.setState({ left: false });
            this.setState({ right: true });
            console.log(this.state.right)
        }
    }

我写了一个函数来打印我的状态。但是在日志中它总是打印错误。为什么我的状态在渲染时没有得到更新?有什么与同步有关的吗?

printDir = () => {
        console.log("up: " + this.state.up.toString());
        console.log("down: " + this.state.down.toString());
        console.log("left: " + this.state.left.toString());
        console.log("right: " + this.state.right.toString());
    }
 <button onClick = {this.printDir}>dir</button>

【问题讨论】:

    标签: reactjs dom keyboard-events setstate


    【解决方案1】:

    我可以在您的 sn-p 中看到两个问题:

    1. 您检查箭头键的 if-else 条件超出了不会触发的侦听器设置范围
    2. 您在这里使用 ES5 函数语法,this 对象将引用您的函数范围,而不是类范围。您可能希望使用 ES6 箭头函数语法来避免 this 对象范围问题

    【讨论】:

      【解决方案2】:

      如果你想使用事件监听器,你必须使用ref props 来访问 DOM。例如&lt;div ref={this.divRef} ...componentDidMount() 你可以写this.divRef.current.addEventListener('keydown', ...)

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 1970-01-01
        • 2018-06-13
        • 2019-06-30
        • 1970-01-01
        • 2019-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多