按键无法进入状态

问题描述 投票:0回答:2
import { useState, useRef, useEffect } from "react";
    
function App() {
  const [message, setMessage] = useState("");
  const inpt = useRef();

  const handleKeyDown = (e) => {
    if (e.key === "Enter") {
      handleClick();
    }
  };

  useEffect(() => {
    inpt.current.addEventListener("keydown", handleKeyDown);
    return () => inpt.current.removeEventListener("keydown", handleKeyDown);
  }, []);

  function handleClick() {
    console.error(message); 
  }
  return (
    <>
      <div>
        <input ref={inpt} type="text" name="" id="" value={message} onChange={(e)=> setMessage(e.target.value)} />
        <button onClick={handleClick}>click</button>
      </div>
    </>
  );
}

export default App;

当我点击按钮时,我可以正确记录

message
,但是当我按“Enter”键时,
message
记录为初始值
""

你能帮我理解为什么会发生这种情况以及我应该做什么吗?

reactjs hook
2个回答
0
投票

由于您在

useEffect
钩子中使用空依赖数组,因此在由于状态更改而重新渲染时,其清理函数将不会被执行,并且
ref
将继续指向陈旧的
input
元素。 为了避免这种情况,您应该添加
message
handleKeydown
作为依赖项。

useEffect(() => {
    inpt.current.addEventListener("keydown", handleKeyDown);
    return () => inpt.current.removeEventListener("keydown", handleKeyDown);
  }, [message]);

0
投票

您需要使

message
成为效果的依赖项,如 Ravi 所说。

const { useEffect, useRef, useState } = React;
    
function App() {
  const [message, setMessage] = useState("");
  const inputRef = useRef();

  const handleKeyDown = (e) => {
    if (e.key === "Enter") {
      handleClick();
    }
  };

  useEffect(() => {
    inputRef.current.addEventListener("keydown", handleKeyDown);
    return () => inputRef.current.removeEventListener("keydown", handleKeyDown);
  }, [message]);

  function handleClick() {
    console.error(`MESSAGE: ${message}`); 
  }
  return (
    <React.Fragment>
      <div>
        <input ref={inputRef} type="text" value={message} onChange={(e)=> setMessage(e.target.value)} />
        <button onClick={handleClick}>Click</button>
      </div>
    </React.Fragment>
  );
}

ReactDOM
  .createRoot(document.getElementById("root"))
  .render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

我更好的方法是使用表格。

如果您在字段上使用引用,则不需要存储状态!

const { useCallback, useRef } = React;
    
function App() {
  const inputRef = useRef();

  const handleSubmit = useCallback((e) => {
    e.preventDefault(); // Do not navigate away from current page
    console.error(`MESSAGE: ${inputRef.current.value}`); 
  }, [inputRef]);
  
  return (
    <React.Fragment>
      <form onSubmit={handleSubmit}>
        <input ref={inputRef} type="text" name="message" />
        <button type="submit">Submit</button>
      </form>
    </React.Fragment>
  );
}

ReactDOM
  .createRoot(document.getElementById("root"))
  .render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.