1

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

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

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

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

谢谢!!

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

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"
      />
    </>
  );
}


4

2 回答 2

2

您必须像这样将焦点登录放在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"
      />
    </>
  );
}

这是链接

于 2020-07-10T17:21:23.383 回答
1

似乎总是这样......你觉得你已经用尽了每一个选项 - 然后你写一个问题,然后你立即找到答案!

在这种情况下 - 将 refs 焦点移动到 watchuseEffectisVisible可以了

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

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

于 2020-07-10T17:21:01.507 回答