我在玩钩子,我试着做到以下几点:

import React, { useState, useRef } from 'react';

const EditableField = () => {
  const [isEditing, setEditing] = useState(false);
  const inputRef = useRef();
  const toggleEditing = () => {
    setEditing(!isEditing);
    if (isEditing) {
      inputRef.current.focus();
    }
  };
  return (
    <>
      {isExpanded && <input ref={inputRef} />}
      <button onClick={toggleEditing}>Edit</button>
    </>
  );
};

这将失败,因为current为空,因为组件尚未重新渲染,输入字段尚未渲染(因此无法聚焦).

正确的方法是什么?我可以使用React Hooks常见问题解答中提出的usePrevious个钩子,但这似乎是一个痛苦的解决方法.

还有别的办法吗?

推荐答案

isEditing发生变化时,可以在每次渲染后使用useEffect钩子运行函数.在该功能中,您可以判断isEditing是否为true并聚焦输入.

Example

const { useState, useRef, useEffect } = React;

const EditableField = () => {
  const [isEditing, setEditing] = useState(false);
  const toggleEditing = () => {
    setEditing(!isEditing);
  };

  const inputRef = useRef(null);

  useEffect(() => {
    if (isEditing) {
      inputRef.current.focus();
    }
  }, [isEditing]);
  
  return (
    <div>
      {isEditing && <input ref={inputRef} />}
      <button onClick={toggleEditing}>Edit</button>
    </div>
  );
};

ReactDOM.render(<EditableField />, document.getElementById("root"));
<script src="https://unpkg.com/react@16.7.0-alpha.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.2/umd/react-dom.production.min.js"></script>
  
<div id="root"></div>

Reactjs相关问答推荐

React onKeyUp不一致地使用快速Shift+键按压

滚动事件监听器在Next.js客户端组件中不触发

在数组对象内的数组上进行映射

如何使我的代码可以接受我想要的每一个链接

根据处于react 状态的数组的名称键,将新对象添加到嵌套的对象数组中

我在Route组件上使用元素属性,这样就不需要ID了吗?

如何动态地改变<; Select >;React和Tailwind元素?

使用 React + Vite 范围化 CSS

React 错误: 只能用作 元素的子元素,从不直接渲染.请将您的 包裹在

React router v5 仅在生产中不适用于嵌套路由

使用jest如何覆盖对象的模拟?我正在使用`jest.mock()`来模拟对象,并希望 for each 测试用例覆盖模拟.

如何更新redux状态存在的输入框

无法使axiosmockadapter正常工作

React 测试库包装器组件

条件渲染元素的测试不起作用

状态链接未传递到路由页面

将props 传递给 NextJS 布局组件

Axios 删除在带有授权令牌的react js 中不起作用

为什么我从另一个组件收到错误?

useEffect 仅在跟随链接后有效,不适用于直接链接