为什么这个输入不会失去焦点?

问题描述 投票:0回答:1

我的背景是WPF/Winforms,我刚刚开始学习React。根据我的理解,每次按键时,以下代码都会重新渲染,因此将重新生成包括文本框在内的元素。因此旧的文本框被丢弃并创建一个新的文本框(失去焦点)。

那么如果旧的文本框具有焦点,并且在我按下某个键后创建了一个新的文本框,那么新的文本框如何仍然具有焦点?

有趣的是,当我用谷歌搜索这个时,人们似乎经历了我所期望的,因为每次按键后你都必须重新聚焦文本框。但对我来说,它似乎神奇地起作用。

我猜React在这里更聪明一点并且回收了元素?或者它仍在重新创建一个新的文本框,但在幕后恢复焦点?

function App() {
  const [userText, setUserText] = useState("empty")

  return (
    <>
      <p>{userText}</p>

      <input type='text' value={userText} onChange={e => setUserText(e.target.value)}/>
    </>
  )
}

export default App
javascript reactjs
1个回答
0
投票

我猜 React 在这里更聪明一点并且回收 元素?或者它仍在重新创建一个新的文本框,但正在恢复 幕后焦点?

也许这个问题的答案就包含在问题本身中。

重点是 React 绝对不会在代码中重新创建输入元素。即使“回收”这个词也可能“有点不准确”。最合适的术语可能是updateReact 在这种情况下更新元素 之所以说问题有答案,问题是说React正在幕后恢复焦点。然而,这里有一个问题是,最新重新渲染返回的最新 JSX 没有任何有关元素焦点的信息,它不携带任何有关它的信息。那么 React 从哪里获取要恢复焦点的信息呢?除了从元素本身获取它之外没有其他方法。这意味着元素本身 - 及其所有属性和值,都保留在 DOM 中,因此无需执行任何额外操作即可保留焦点。

现在关于这里发生的每一次击键。状态

userText

正在更新。由于这是状态更新,因此组件将在每次击键时重新渲染。然而,每次击键新返回的每个 JSX 与之前的 JSX 的区别仅在于 props valuevalue 属性将继续获取该状态的最新文本。因此,为了将最新的 JSX 与相应的 DOM 元素同步,它只需要“更新”同一输入 DOM 元素的 value 属性。这样,React 只执行最少的必要操作来使 DOM 元素与最新的 JSX。 如您所知,到目前为止我们一直在讨论受控输入。

让我们以不受控制的输入为例。下面的代码显示了相同的内容。

在这里,即使组件每 5 秒重新渲染一次,运行时所做的输入仍被保留。请记住,这是不受控制的输入,因此没有相同的状态进行备份。运行时的输入仍然被保留。它澄清了 React 不会在每次渲染时触及输入元素。

App.js

import { useState, useEffect } from 'react'; export default function App() { const [autoRender, setAutoRender] = useState(); useEffect(() => { const timer = setInterval(() => { setAutoRender(Math.random()); }, 5000); return () => clearInterval(timer); }, []); return ( <> <h3>A component auto-renders in 5 seconds</h3> <label> An uncontrolled input still retains your input on every render </label> <input /> <br /> <br /> <i>The latest state : {autoRender}</i> </> ); }

试运行

enter image description here 结论是:

    当应用程序启动时,它会进行初始渲染。在初始渲染期间,返回的 JSX 中的每个元素都必须在 DOM 中创建。 React 使用 APIappendChild() 来创建所有这些元素。 React 在这里无法做任何优化。
  1. 但是,在每个后续渲染中,Reacts 都会将最新的 JSX 与之前的 JSX 进行比较。因此它找到了 JSX 的增量。 React 仅根据此 JSX 增量更新 DOM。这可能包括元素删除、元素添加和元素更新。这完全取决于组件中的渲染逻辑。这是 React 真正发挥作用的时候了。它本质上优化了 DOM 更新。
© www.soinside.com 2019 - 2024. All rights reserved.