React:定义使用状态的键处理程序的最佳实践是什么?

问题描述 投票:0回答:1

我正在使用 React。我使用功能组件是因为我知道这是现代的方式。我想定义一个访问组件状态的键处理程序。直观优雅的方法行不通。

import React, {useState,useEffect} from "react"

我尝试了3种方法:

方法1

export default function CounterApp()
{
    const [counter,setCounter] = useState(0);

    useEffect(
        () => document.addEventListener('keydown', 
            (e) => {
                console.log("Got keystroke", e.key, counter);
                if (e.key === "1") {
                    setCounter(counter+1);
                }
            })
    ,[]);

    console.log("render");
    return  <div>The counter is: {counter} </div>
}

方法二:

export default function CounterApp()
{
    const [counter,setCounter] = useState(0);

    useEffect(
        () => document.addEventListener('keydown', keyhandler)
    ,[]);

    function keyhandler(e)  
    {
        console.log("Got keystroke", e.key, counter);
        if (e.key === "1") {
            setCounter(counter+1);
        }
    }

    console.log("render");
    return  <div>The counter is: {counter} </div>
}

方法三:

export default function CounterApp()
{
    const [counter,setCounter] = useState(0);

    useEffect(
        () => {
            document.addEventListener('keydown', keyhandler);
            return () => document.removeEventListener('keydown', keyhandler);
        }
    ,[counter]);

    function keyhandler(e)  
    {
        console.log("Got keystroke", e.key, counter);
        if (e.key === "1") {
            setCounter(counter+1);
        }
    }

    console.log("render");
    return  <div>The counter is: {counter} </div>
}

方法3确实有效。但这似乎需要大量输入,可能效率低下(频繁调用 useEffect),并且容易出错,所以我想知道为什么更直接的方法不起作用。我更愿意在组件的生命周期中仅添加一次事件侦听器,添加一个永远不会更改的函数(因此无需将其添加为 useEffect 依赖项),尽管该函数引用了一个会更改的状态变量。 React 是否真的需要在状态变量输入发生变化时重新解析函数定义?第三种方法是否正确且最佳?前两种方法有什么问题吗?

reactjs react-hooks
1个回答
0
投票

方法3很接近,但是你不应该在效果外部定义

keyHandler
,你应该在效果内部定义它。如果您使用函数更新状态,则只需在安装时应用效果,而不是在计数器更改时应用效果:

export default function CounterApp() {
    const [counter,setCounter] = useState(0);

    useEffect(() => {
        const keyHandler = (e) => {
          if(e.key === "1") setCounter(c => c+1)
        }
    
        document.addEventListener('keydown', keyhandler);
        return () => document.removeEventListener('keydown', keyhandler);
    },[]);

    console.log("render");
    return  <div>The counter is: {counter} </div>
}
© www.soinside.com 2019 - 2024. All rights reserved.