我有一个父组件,我在其中初始化一些状态,然后将其传递给子组件,以便它们可以更新。但是,当触发更新时,组件树将被重新渲染,并且我的输入将失去焦点。添加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>
);
}
因此,现在,当我开始在StartScreen.tsx
上的InputField
(它基本上是<input>
的包装器(上输入时,由于组件被完全重新渲染,输入不断失去焦点(我可以在DOM中看到它(。
发生这种情况是因为您正在将函数传递给Route
的component
道具(我假设您使用的是react-router-dom
(:
来自文档:
如果为组件道具提供内联函数每次渲染都创建一个新组件。这导致现有组件卸载和新组件安装,而不是更新现有组件。
要解决此问题,请使用render
道具:
<Route
exact
path="/"
render={() => (
<StartScreen
useVal={useVal}
/>
)}
/>
这允许在没有上面解释的不希望的重新安装。