我有一个父组件,在其中初始化了一些状态,然后将其传递给子组件,以便它们可以更新该状态。但是,触发更新时,将重新渲染组件树,而我的输入将失去焦点。添加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中看到它)。
答案 0 :(得分:5)
发生这种情况是因为您正在向Route
的{{1}}道具传递函数(我假设您正在使用component
):
来自docs:
如果您向组件prop提供内联函数,您将 在每个渲染器中创建一个新组件。这导致现有的 组件卸载和新组件安装,而不仅仅是 更新现有组件。
要解决此问题,请使用react-router-dom
道具:
render
这可以方便地进行内联渲染和换行,而无需 上面说明了不希望的重新安装。