React通过下钩导致重新呈现并失去对输入的关注

时间:2020-08-19 17:25:47

标签: javascript reactjs react-hooks

我有一个父组件,在其中初始化了一些状态,然后将其传递给子组件,以便它们可以更新该状态。但是,触发更新时,将重新渲染组件树,而我的输入将失去焦点。添加key并没有帮助。

// App.tsx

export function App(props) {
  const useVal = useState("");

  return (
    <Router>
      <Switch>
        <Route
          exact
          path="/"
          component={() => (
            <StartScreen
              useVal={useVal}
            />
          )}
        />
        // ...
    </Router>
  );
}
// StartScreen.tsx

interface StartScreenProps {
  useVal: [string, React.Dispatch<React.SetStateAction<string>>];
}

function bindState<T>(
  [value, setState]: [T, React.Dispatch<React.SetStateAction<T>>]
) {
  return {
    value,
    onChange: ({ value }: { value: T }) => setState(value)
  }
}

export const StartScreen = (props: StartScreenProps) => {
  return (
    <form>
      <InputField
        key="myInput"
        {...bindState(props.useVal)}
      />
    </form>
  );
}

因此,现在,当我开始在InputField上的<input>(基本上是StartScreen.tsx的包装器)上键入内容时,由于组件完全重新渲染(我可以在DOM中看到它)。

1 个答案:

答案 0 :(得分:5)

发生这种情况是因为您正在向Route的{​​{1}}道具传递函数(我假设您正在使用component):

来自docs

如果您向组件prop提供内联函数,您将 在每个渲染器中创建一个新组件。这导致现有的 组件卸载和新组件安装,而不仅仅是 更新现有组件。


要解决此问题,请使用react-router-dom道具:

render

这可以方便地进行内联渲染和换行,而无需 上面说明了不希望的重新安装。