Это происходит потому, что хук useState
не "привязан" к вашему SearchComponent
, а к вашему MyInput
компоненту.Всякий раз, когда вы вызываете updateCitySearch()
, вы изменяете состояние MyInput
, таким образом вынуждая компонент whole выполнить повторную визуализацию.
SearchComponent
, явно определено внутри MyInput
.Когда citySearch-state
обновляется, SearchComponent
теряет фокус, потому что начальный virual DOM
, окружающий его, больше не является целым, вместо этого у вас есть совершенно новый кусок DOM.По сути, вы создаете совершенно новый SearchComponent
каждый раз, когда MyInput
обновляется по состоянию.
Рассмотрите следующий пример:
function App() {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered App again"); //always prints
const SearchComponent = () => {
console.log("rendered Search"); //always prints
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}
Каждый раз, когда вы обновляете состояние, вы должныактивировать console.log()
, компонент приложения перерисовывается, а SearchComponent
создается заново.Новая итерация myInput
отображается каждый раз, и создается новый SearchComponent
.
Но если бы вы определили useState
внутри SearchComponent
, то только SearchComponent
будет повторно визуализироваться, когдасостояние изменяется, в результате чего исходный компонент myInput
остается неизменным, а текущий SearchComponent
не изменяется.
function App() {
console.log("rendered App again"); //would never print a 2nd time.
const SearchComponent = () => {
const [citySearch, updateCitySearch] = useState("");
console.log("rendered Search"); //would print with new state change
const searchCityClick = () => {
alert(citySearch);
};
return (
<div>
<input
value={citySearch}
onChange={e => {
updateCitySearch(e.target.value);
}}
/>
<button onClick={searchCityClick}>Search</button>
</div>
);
};
return (
<div>
<div>
<SearchComponent />
</div>
</div>
);
}