Точно то же самое о бесконечном l oop упоминается в React
документах здесь . Таким образом, причина бесконечного l oop заключается в том, что в функции рендеринга контекста вы создаете новое значение каждый вызов времени рендеринга.
render() {
return (
<Context.Provider
// ! value object creates every time render is called - it's bad
value={{ ...this.state, handleSearch: this.handleSearch }}
>
{this.props.children}
</Context.Provider>
);
}
Это вызывает каждый потребитель должен обновляться при обновлении состояния контекста. Итак, если вы поместите context
в массив зависимостей useEffect
, в конечном итоге это приведет к бесконечному l oop, потому что значение context
всегда отличается. Вот что происходит:
Контекст выполняет поисковый запрос.
Обновление состояния контекста с новыми данными, что приводит к повторному отображению всех потребителей.
В контексте потребителя useEffect
видит, что значение контекста было обновлено, и вызывает setTimeout
, который вызовет другой поиск в поставщике контекста через 500 мс.
- Потребитель вызывает контекст для создания другого поискового запроса, и мы получаем бесконечное l oop!
Решение состоит в том, чтобы сохранить значение контекста в том же объекте, при этом обновляя только его свойства. Это можно сделать, поместив все необходимые свойства в контекстное состояние. Вот так:
export class MovieStore extends Component {
handleSearch = async term => {
try {
if (term !== "") {
const response = await axios.get("http://www.omdbapi.com/", {
params: {
apikey: "15bfc1e3",
s: term
}
});
this.setState({ searchResults: response.data.Search });
}
} catch (error) {
console.log(error);
}
};
state = {
searchResults: [],
handleSearch: this.handleSearch // <~ put method directly to the state
};
render() {
return (
<Context.Provider value={this.state}> // <~ Just returning state here
{this.props.children}
</Context.Provider>
);
}
}
Надеюсь, это поможет <3 </p>