同时更改css代码和设置焦点(为什么不起作用?)

qjp7pelc  于 2023-02-17  发布在  其他
关注(0)|答案(2)|浏览(160)

我试着做...第一次渲染时屏幕上没有输入。当我点击按钮时,输入出现了。我想同时在输入上设置焦点。
让我来解释一下我做了什么。起初,输入在屏幕上是不可见的。因为Box的display属性(div标签),这是input的父组件,是none。但是当我点击按钮时,这个框的display属性变成了block。这是我要做的。我要把焦点放在屏幕上的输入上。在按钮被点击时调用的函数中,我写了一段代码来改变css代码并将焦点设置在输入上,但是它没有起作用,请看下面的代码。

const [inputDisplay, setInputDisplay] = useState("none");
const refInput = useRef(null);

const HandleShowInput = () => {
  setInputDisplay("block");
  refInput.current.focus();
};

return (
  <>
    <Box theme={inputDisplay}>
      <Input ref={refInput}/>
    <Box/>
    <Button onClick={HandleShowInput}/>
  </>
)

下面是动态更改Box组件的css的代码。

import styled, { css } from "styled-components";

const Box = ({ children, ...props }) => {
    return <StBox {...props}>{children}</StBox>;
};

const StBox = styled.div`
  ${({ theme }) => {
    switch (theme) {
      case "block":
        return css`
          display: ${theme} !important;
        `;
      default:
        break;
    }
  }}
`;

export default Box;

但是下面的代码是工作的。我把它放在useEffect中来分离代码。

const [inputDisplay, setInputDisplay] = useState("none");
const refInput = useRef(null);

const HandleShowInput = () => {
  setInputDisplay("block");
};

useEffect(() => {
    refInput.current.focus();
}, [inputDisplay]);

return (
  <>
    <Box theme={inputDisplay}>
      <Input ref={refInput}/>
    <Box/>
    <Button onClick={HandleShowInput}/>
  </>
)

我想知道为什么大写字母不起作用,小写字母起作用。我不知道我是否缺乏react知识或css知识。我将非常感激,如果你能帮助一个初学者在react。此外,请理解,如果有任何不自然的句子,因为我不擅长英语。谢谢。

k4emjkb1

k4emjkb11#

当你试图通过HandleShowInput这个函数来聚焦输入元素时。这里发生了两件事,你改变了输入的状态和焦点。它会聚焦输入,但是时间会很短,以至于我们看不到用户界面。同样由于状态的改变,渲染会发生,ref会再次得到输入元素。因此你看不到这个聚焦的输入
但是在使用useEffect的情况下,这会在渲染之后发生。之后没有渲染。所以我们可以看到聚焦的输入

yacmzcpb

yacmzcpb2#

思考React的方式与Javascript稍有不同。
你可能会期望下面两个以同样的方式运行。

setInputDisplay("block");
  refInput.current.focus();

以及

document.querySelector('#canFocus').style.display='block'
document.querySelector('#canFocus').focus();

不~不是的。JS阻塞Dom然后聚焦它,它工作的很好。但是React的工作原理和下面的代码一样。

setTimeout(()=>{
  // next react render cycle callback
  document.querySelector('#canNotFocus').style.display='block'
}, 1000)
document.querySelector('#canNotFocus').focus();

调用focus方法时,dom显示为none;您在react中设置状态,ReactDom将在功能组件的下一个生命周期中将其作为显示块。https://codesandbox.io/s/confident-wilson-q01ktj?file=/index.html

相关问题