【问题标题】:React useRef / forwardRef not working as expected when focusing a radio button聚焦单选按钮时反应 useRef / forwardRef 未按预期工作
【发布时间】:2020-10-31 11:33:37
【问题描述】:

我在这里整理了一个小演示:https://codesandbox.io/s/bold-meitner-r3wzq?file=/src/App.js

当我单击按钮以显示并专注于我的第一个单选按钮时 - 我的单选样式未应用。不过,如果您紧接着按空格键,它会聚焦正确的元素。

奇怪的是,如果我在 1 毫秒超时后集中注意力,它会按预期工作。显然,这更像是一种 hack,而不是一种解决方案......

我觉得我在这里遗漏了一些非常简单的东西,任何帮助都会很棒!

谢谢!!

或者 - 这是复制所需的所有代码:

import React from "react";
import styled from "styled-components";
import "./styles.css";

const { useRef, forwardRef, useState } = React;

const Button = ({ onClick }) => (
  <button onClick={onClick}>Click me to show and focus radio buttons</button>
);

const Fieldset = styled.fieldset`
  display: ${props => (props.isVisible ? "block" : "none")};

  input {
    :focus {
      outline: 5px solid red;
    }
  }
`;

const RadioButtons = forwardRef(({ isVisible, legend }, ref) => (
  <Fieldset isVisible={isVisible}>
    <legend>{legend}</legend>
    <label for="one">One</label>
    <input ref={ref} type="radio" id="one" name="radios" />
    <label for="two">Two</label>
    <input type="radio" id="two" name="radios" />
  </Fieldset>
));

export default function App() {
  const [isVisible, setIsVisible] = useState(false);
  const inputRef = useRef();

  const focusInput = () => {
    setIsVisible(true);

    // This doesn't work as expected
    inputRef.current.focus();

    // This does - But it definitely doesn't feel like a "solution"
    // setTimeout(() => {
    //   inputRef.current.focus();
    // }, 1);
  };

  return (
    <>
      <Button onClick={focusInput} />
      <RadioButtons
        isVisible={isVisible}
        ref={inputRef}
        legend="Radio Legend"
      />
    </>
  );
}


【问题讨论】:

    标签: reactjs use-ref react-forwardref


    【解决方案1】:

    你必须像这样将焦点登录放在useEffect钩子中

    export default function App() {
      const [isVisible, setIsVisible] = useState(false);
      const inputRef = useRef();
    
      const focusInput = () => {
        setIsVisible(true);
      };
    
      React.useEffect(() => {
        if (isVisible) {
          inputRef.current.focus();
        }
      }, [isVisible]);
    
      return (
        <>
          <Button onClick={focusInput} />
          <RadioButtons
            isVisible={isVisible}
            ref={inputRef}
            legend="Radio Legend"
          />
        </>
      );
    }
    

    这里是link

    【讨论】:

    • 哈哈,但似乎您自己找到了解决方案,所以答案没有多大意义:)
    • 我很幸运到达那里!我仍然感谢您的帮助! :)
    【解决方案2】:

    似乎总是如此……您觉得自己已经用尽了所有选择-然后您写了一个问题,然后您立即找到了答案!

    在这种情况下 - 将 refs 焦点移到 useEffect 上,观察 isVisible 就可以了

    useEffect(() => {
        // I check here because my actual code toggles isVisible 
        if (isVisible) inputRef.current.focus();
    }, [isVisible]);
    

    仍然有兴趣看看这是否可以以更好的方式完成

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 2020-09-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多