Useeffect react что это
Hooks API Reference
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
This page describes the APIs for the built-in Hooks in React.
If you’re new to Hooks, you might want to check out the overview first. You may also find useful information in the frequently asked questions section.
Returns a stateful value, and a function to update it.
During the initial render, the returned state ( state ) is the same as the value passed as the first argument ( initialState ).
The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.
During subsequent re-renders, the first value returned by useState will always be the most recent state after applying updates.
React guarantees that setState function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list.
The ”+” and ”-” buttons use the functional form, because the updated value is based on the previous value. But the “Reset” button uses the normal form, because it always sets the count back to the initial value.
If your update function returns the exact same value as the current state, the subsequent rerender will be skipped completely.
Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
Lazy initial state
The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded. If the initial state is the result of an expensive computation, you may provide a function instead, which will be executed only on the initial render:
Bailing out of a state update
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)
Accepts a function that contains imperative, possibly effectful code.
Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.
By default, effects run after every completed render, but you can choose to fire them only when certain values have changed.
Cleaning up an effect
Often, effects create resources that need to be cleaned up before the component leaves the screen, such as a subscription or timer ID. To do this, the function passed to useEffect may return a clean-up function. For example, to create a subscription:
The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section.
Although useEffect is deferred until after the browser has painted, it’s guaranteed to fire before any new renders. React will always flush a previous render’s effects before starting a new update.
Conditionally firing an effect
The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its dependencies changes.
However, this may be overkill in some cases, like the subscription example from the previous section. We don’t need to create a new subscription on every update, only if the source prop has changed.
To implement this, pass a second argument to useEffect that is the array of values that the effect depends on. Our updated example now looks like this:
Now the subscription will only be recreated when props.source changes.
If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array values change too often.
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ( [] ) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.
If you pass an empty array ( [] ), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.
We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.
The array of dependencies is not passed as arguments to the effect function. Conceptually, though, that’s what they represent: every value referenced inside the effect function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
Accepts a context object (the value returned from React.createContext ) and returns the current context value for that context. The current context value is determined by the value prop of the nearest above the calling component in the tree.
Don’t forget that the argument to useContext must be the context object itself:
A component calling useContext will always re-render when the context value changes. If re-rendering the component is expensive, you can optimize it by using memoization.
useContext(MyContext) only lets you read the context and subscribe to its changes. You still need a above in the tree to provide the value for this context.
Putting it together with Context.Provider
This example is modified for hooks from a previous example in the Context Advanced Guide, where you can find more information about when and how to use Context.
The following Hooks are either variants of the basic ones from the previous section, or only needed for specific edge cases. Don’t stress about learning them up front.
useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.
Here’s the counter example from the useState section, rewritten to use a reducer:
React guarantees that dispatch function identity is stable and won’t change on re-renders. This is why it’s safe to omit from the useEffect or useCallback dependency list.
Specifying the initial state
There are two different ways to initialize useReducer state. You may choose either one depending on the use case. The simplest way is to pass the initial state as a second argument:
React doesn’t use the state = initialState argument convention popularized by Redux. The initial value sometimes needs to depend on props and so is specified from the Hook call instead. If you feel strongly about this, you can call useReducer(reducer, undefined, reducer) to emulate the Redux behavior, but it’s not encouraged.
It lets you extract the logic for calculating the initial state outside the reducer. This is also handy for resetting the state later in response to an action:
Bailing out of a dispatch
If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)
Returns a memoized callback.
Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate ).
The array of dependencies is not passed as arguments to the callback. Conceptually, though, that’s what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.
Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
If no array is provided, a new value will be computed on every render.
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.
The array of dependencies is not passed as arguments to the function. Conceptually, though, that’s what they represent: every value referenced inside the function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.
A common use case is to access a child imperatively:
You might be familiar with refs primarily as a way to access the DOM. If you pass a ref object to React with
However, useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.
Prefer the standard useEffect when possible to avoid blocking visual updates.
useDebugValue can be used to display a label for custom hooks in React DevTools.
For example, consider the useFriendStatus custom Hook described in “Building Your Own Hooks”:
We don’t recommend adding debug values to every custom Hook. It’s most valuable for custom Hooks that are part of shared libraries.
Defer formatting debug values
In some cases formatting a value for display might be an expensive operation. It’s also unnecessary unless a Hook is actually inspected.
For this reason useDebugValue accepts a formatting function as an optional second parameter. This function is only called if the Hooks are inspected. It receives the debug value as a parameter and should return a formatted display value.
For example a custom Hook that returned a Date value could avoid calling the toDateString function unnecessarily by passing the following formatter:
Продвинутые React Hooks: подробный разбор useEffect
С выходом React 16.8 в 2019 году React Hooks наконец-то стали доступны для использования в пригодных для эксплуатации приложениях. Хуки позволяют React-разработчикам делать функциональные компоненты с отслеживанием состояния и не использовать классовые компоненты.
UseEffect — один из трёх больших встроенных React Hooks и один из самых популярных хуков. Он даёт возможность создавать условные изменения, ссылающиеся на состояние программы внутри функционального компонента.
Ближе к концу статьи вы узнаете, как и когда реализовывать этот хук для создания реактивных программ, и поймёте, почему он так часто используется React-разработчиками.
В статье мы рассмотрим следующие вопросы и темы:
Что такое React Hooks?
В React есть функциональные компоненты, которые не содержат внутреннего состояния. А ещё есть классовые компоненты, добавляющие в программу логику с отслеживанием состояния и позволяющие использовать методы жизненного цикла.
Многие разработчики были против такого подхода, так как классовым компонентам для поддержки внутренних состояний требуются классы ES6.
И вот была предложена альтернатива в виде React Hooks.
React Hooks — это функции, которые позволяют подцепиться к состоянию и жизненному циклу React из функциональных компонентов. Это даёт возможность использовать React без классов, которые многим не нравятся из-за их зависимости от вызовов this JavaScript. А главное — хуки включаются по желанию и работают с имеющимся кодом.
Существует несколько встроенных хуков (таких как useEffect или useState ), которые ссылаются на стандартные внутренние состояния. Есть также возможность создавать пользовательские хуки, ссылающиеся на выбранные состояния.
Вот самые популярные встроенные хуки:
Преимущества React Hooks:
Сравнение реализации компонентов с классами и хуками
Хуки предназначены для всего того, на что способны классы, и могут даже больше. Посмотрим, как преобразится старый код на React с использованием хуков вместо классов.
Вот старый код на React без хуков:
Для этого внесём в код следующие изменения:
Вот как теперь выглядит то же самое приложение на React с хуками:
Хуки легко задействовать в приложении, и код при этом становится более удобным для восприятия!
Что представляет собой хук useEffect?
useEffect — один из самых популярных хуков, ведь он выполняет побочные эффекты в функциональных компонентах. Присмотримся к нему повнимательнее, чтобы понять, как это происходит.
Хук useEffect позволяет запускать дополнительный код после того, как React обновит DOM.
Синтаксис
Хук useEffect принимает два аргумента:
Первый аргумент — это функция обратного вызова, которая по умолчанию запускается после каждого отображения.
Второй аргумент — это опциональный массив зависимостей, который указывает хуку на выполнение обратного вызова только при наличии изменения в целевом состоянии. Хук сравнивает значение предыдущего и текущего состояния каждой зависимости. Если эти два значения не совпадают, хук использует обратный вызов первого аргумента.
Массивы зависимостей переопределяют поведение обратного вызова по умолчанию и обеспечивают, что хук проигнорирует всё остальное в области компонента.
Примеры использования
Вот типичные сценарии применения useEffect :
В каждом из этих случаев useEffect используется вместо метода жизненного цикла.
Использование массива зависимостей с хуком useEffect Hook
Для оптимизации хука useEffect необходимо правильно задействовать массивы зависимостей. Важно использовать эти хуки для предотвращения ненужных повторных отображений, даже когда ничего не меняется.
Приведённый ниже код выводит на страницу полученное сообщение, но не использует массив зависимостей.
Всё вроде хорошо, но при открытии консоли браузера обнаруживается, что сообщение >> Loading Message несколько раз перезапускалось.
Сообщение не изменилось, поэтому оптимизируем всё это: сообщения будут загружаться и получаться только раз.
Секрет в добавлении пустого массива зависимостей. Строки 8–10 просто заменяются на:
По умолчанию хук useEffect запускается после каждого повторного отображения. А с массивом зависимостей он запускается один раз и затем запускается снова при каждом изменении передаваемой зависимости. Пустой массив не оставляет условий для повторного запуска хука, обеспечивая получение сообщения только при первом отображении.
Запуск функции useEffect с изменением состояния или пропсов
Массивы зависимостей также полезны при создании адаптивных приложений. Но это должны быть заполненные массивы.
Возьмём приложение на React, позволяющее пользователям устанавливать псевдоним, вводя его в поле ввода. После установки псевдонима приложение получает персонализированное приветственное сообщение из внешнего API.
Вот и всё, мы только что создали метод componentDidUpdate с помощью хуков!
Что дальше?
Мы убедились, что React Hooks — это мощный инструмент, который позволяет обойти многие неудобные элементы старого синтаксиса React.
Продвинутые React Hooks: подробный разбор useEffect
Feb 22 · 7 min read
С выходом React 16.8 в 2019 году React Hooks наконец-то стали доступны для использования в пригодных для эксплуатации приложениях. Хуки позволяют React-разработчикам делать функциональные компоненты с отслеживанием состояния и не использовать классовые компоненты.
UseEffect — один из трёх больших встроенных React Hooks и один из самых популярных хуков. Он даёт возможность создавать условные изменения, ссылающиеся на состояние программы внутри функционального компонента.
Ближе к концу статьи вы узнаете, как и когда реализовывать этот хук для создания реактивных программ, и поймёте, почему он так часто используется React-разработчиками.
В статье мы рассмотрим следующие вопросы и темы:
Что такое React Hooks?
В React есть фу н кциональные компоненты, которые не содержат внутреннего состояния. А ещё есть классовые компоненты, добавляющие в программу логику с отслеживанием состояния и позволяющие использовать методы жизненного цикла.
Многие разработчики были против такого подхода, так как классовым компонентам для поддержки внутренних состояний требуются классы ES6.
И вот была предложена альтернатива в виде React Hooks.
React Hooks — это функции, которые позволяют подцепиться к состоянию и жизненному циклу React из функциональных компонентов. Это даёт возможность использовать React без классов, которые многим не нравятся из-за их зависимости от вызовов this JavaScript. А главное — хуки включаются по желанию и работают с имеющимся кодом.
Существует несколько встроенных хуков (таких как useEffect или useState ), которые ссылаются на стандартные внутренние состояния. Есть также возможность создавать пользовательские хуки, ссылающиеся на выбранные состояния.
Вот самые популярные встроенные хуки:
Преимущества React Hooks:
Сравнение реализации компонентов с классами и хуками
Хуки предназначены для всего того, на что способны классы, и могут даже больше. Посмотрим, как преобразится старый код на React с использованием хуков вместо классов.
Вот старый код на React без хуков:
Для этого внесём в код следующие изменения:
Вот как теперь выглядит то же самое приложение на React с хуками:
Хуки легко задействовать в приложении, и код при этом становится более удобным для восприятия!
Что представляет собой хук useEffect?
useEffect — один из самых популярных хуков, ведь он выполняет побочные эффекты в функциональных компонентах. Присмотримся к нему повнимательнее, чтобы понять, как это происходит.
Хук useEffect позволяет запускать дополнительный код после того, как React обновит DOM.
Синтаксис
Хук useEffect принимает два аргумента:
Первый аргумент — это функция обратного вызова, которая по умолчанию запускается после каждого отображения.
Второй аргумент — это опциональный массив зависимостей, который указывает хуку на выполнение обратного вызова только при наличии изменения в целевом состоянии. Хук сравнивает значение предыдущего и текущего состояния каждой зависимости. Если эти два значения не совпадают, хук использует обратный вызов первого аргумента.
Массивы зависимостей переопределяют поведение обратного вызова по умолчанию и обеспечивают, что хук проигнорирует всё остальное в области компонента.
Примеры использования
Вот типичные сценарии применения useEffect :
В каждом из этих случаев useEffect используется вместо метода жизненного цикла.
Использование массива зависимостей с хуком useEffect Hook
Для оптимизации хука useEffect необходимо правильно задействовать массивы зависимостей. Важно использовать эти хуки для предотвращения ненужных повторных отображений, даже когда ничего не меняется.
Приведённый ниже код выводит на страницу полученное сообщение, но не использует массив зависимостей.
Всё вроде хорошо, но при открытии консоли браузера обнаруживается, что сообщение >> Loading Message несколько раз перезапускалось.
Сообщение не изменилось, поэтому оптимизируем всё это: сообщения будут загружаться и получаться только раз.
Секрет в добавлении пустого массива зависимостей. Строки 8–10 просто заменяются на:
По умолчанию хук useEffect запускается после каждого повторного отображения. А с массивом зависимостей он запускается один раз и затем запускается снова при каждом изменении передаваемой зависимости. Пустой массив не оставляет условий для повторного запуска хука, обеспечивая получение сообщения только при первом отображении.
Запуск функции useEffect с изменением состояния или пропсов
Массивы зависимостей также полезны при создании адаптивных приложений. Но это должны быть заполненные массивы.
Возьмём приложение на React, позволяющее пользователям устанавливать псевдоним, вводя его в поле ввода. После установки псевдонима приложение получает персонализированное приветственное сообщение из внешнего API.
Using the Effect Hook
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
The Effect Hook lets you perform side effects in function components:
This snippet is based on the counter example from the previous page, but we added a new feature to it: we set the document title to a custom message including the number of clicks.
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. Whether or not you’re used to calling these operations “side effects” (or just “effects”), you’ve likely performed them in your components before.
There are two common kinds of side effects in React components: those that don’t require cleanup, and those that do. Let’s look at this distinction in more detail.
Effects Without Cleanup
Sometimes, we want to run some additional code after React has updated the DOM. Network requests, manual DOM mutations, and logging are common examples of effects that don’t require a cleanup. We say that because we can run them and immediately forget about them. Let’s compare how classes and Hooks let us express such side effects.
Example Using Classes
In React class components, the render method itself shouldn’t cause side effects. It would be too early — we typically want to perform our effects after React has updated the DOM.
Note how we have to duplicate the code between these two lifecycle methods in class.
This is because in many cases we want to perform the same side effect regardless of whether the component just mounted, or if it has been updated. Conceptually, we want it to happen after every render — but React class components don’t have a method like this. We could extract a separate method but we would still have to call it in two places.
Now let’s see how we can do the same with the useEffect Hook.
Example Using Hooks
We’ve already seen this example at the top of this page, but let’s take a closer look at it:
What does useEffect do? By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.
Why is useEffect called inside a component? Placing useEffect inside the component lets us access the count state variable (or any props) right from the effect. We don’t need a special API to read it — it’s already in the function scope. Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.
Does useEffect run after every render? Yes! By default, it runs both after the first render and after every update. (We will later talk about how to customize this.) Instead of thinking in terms of “mounting” and “updating”, you might find it easier to think that effects happen “after render”. React guarantees the DOM has been updated by the time it runs the effects.
Now that we know more about effects, these lines should make sense:
We declare the count state variable, and then we tell React we need to use an effect. We pass a function to the useEffect Hook. This function we pass is our effect. Inside our effect, we set the document title using the document.title browser API. We can read the latest count inside the effect because it’s in the scope of our function. When React renders our component, it will remember the effect we used, and then run our effect after updating the DOM. This happens for every render, including the first one.
Experienced JavaScript developers might notice that the function passed to useEffect is going to be different on every render. This is intentional. In fact, this is what lets us read the count value from inside the effect without worrying about it getting stale. Every time we re-render, we schedule a different effect, replacing the previous one. In a way, this makes the effects behave more like a part of the render result — each effect “belongs” to a particular render. We will see more clearly why this is useful later on this page.
Effects with Cleanup
Earlier, we looked at how to express side effects that don’t require any cleanup. However, some effects do. For example, we might want to set up a subscription to some external data source. In that case, it is important to clean up so that we don’t introduce a memory leak! Let’s compare how we can do it with classes and with Hooks.
Example Using Classes
Notice how componentDidMount and componentWillUnmount need to mirror each other. Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect.
Eagle-eyed readers may notice that this example also needs a componentDidUpdate method to be fully correct. We’ll ignore this for now but will come back to it in a later section of this page.
Example Using Hooks
Let’s see how we could write this component with Hooks.
You might be thinking that we’d need a separate effect to perform the cleanup. But code for adding and removing a subscription is so tightly related that useEffect is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up:
Why did we return a function from our effect? This is the optional cleanup mechanism for effects. Every effect may return a function that cleans up after it. This lets us keep the logic for adding and removing subscriptions close to each other. They’re part of the same effect!
When exactly does React clean up an effect? React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time. We’ll discuss why this helps avoid bugs and how to opt out of this behavior in case it creates performance issues later below.
We don’t have to return a named function from the effect. We called it cleanup here to clarify its purpose, but you could return an arrow function or call it something different.
We’ve learned that useEffect lets us express different kinds of side effects after a component renders. Some effects might require cleanup so they return a function:
Other effects might not have a cleanup phase, and don’t return anything.
The Effect Hook unifies both use cases with a single API.
If you feel like you have a decent grasp on how the Effect Hook works, or if you feel overwhelmed, you can jump to the next page about Rules of Hooks now.
Tips for Using Effects
We’ll continue this page with an in-depth look at some aspects of useEffect that experienced React users will likely be curious about. Don’t feel obligated to dig into them now. You can always come back to this page to learn more details about the Effect Hook.
Tip: Use Multiple Effects to Separate Concerns
One of the problems we outlined in the Motivation for Hooks is that class lifecycle methods often contain unrelated logic, but related logic gets broken up into several methods. Here is a component that combines the counter and the friend status indicator logic from the previous examples:
So, how can Hooks solve this problem? Just like you can use the State Hook more than once, you can also use several effects. This lets us separate unrelated logic into different effects:
Hooks let us split the code based on what it is doing rather than a lifecycle method name. React will apply every effect used by the component, in the order they were specified.
Explanation: Why Effects Run on Each Update
If you’re used to classes, you might be wondering why the effect cleanup phase happens after every re-render, and not just once during unmounting. Let’s look at a practical example to see why this design helps us create components with fewer bugs.
But what happens if the friend prop changes while the component is on the screen? Our component would continue displaying the online status of a different friend. This is a bug. We would also cause a memory leak or crash when unmounting since the unsubscribe call would use the wrong friend ID.
In a class component, we would need to add componentDidUpdate to handle this case:
Forgetting to handle componentDidUpdate properly is a common source of bugs in React applications.
Now consider the version of this component that uses Hooks:
It doesn’t suffer from this bug. (But we also didn’t make any changes to it.)
There is no special code for handling updates because useEffect handles them by default. It cleans up the previous effects before applying the next effects. To illustrate this, here is a sequence of subscribe and unsubscribe calls that this component could produce over time:
This behavior ensures consistency by default and prevents bugs that are common in class components due to missing update logic.
Tip: Optimizing Performance by Skipping Effects
In some cases, cleaning up or applying the effect after every render might create a performance problem. In class components, we can solve this by writing an extra comparison with prevProps or prevState inside componentDidUpdate :
This requirement is common enough that it is built into the useEffect Hook API. You can tell React to skip applying an effect if certain values haven’t changed between re-renders. To do so, pass an array as an optional second argument to useEffect :
This also works for effects that have a cleanup phase:
In the future, the second argument might get added automatically by a build-time transformation.
If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders. Learn more about how to deal with functions and what to do when the array changes too often.
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ( [] ) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.
If you pass an empty array ( [] ), the props and state inside the effect will always have their initial values. While passing [] as the second argument is closer to the familiar componentDidMount and componentWillUnmount mental model, there are usually better solutions to avoid re-running effects too often. Also, don’t forget that React defers running useEffect until after the browser has painted, so doing extra work is less of a problem.
We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.
Congratulations! This was a long page, but hopefully by the end most of your questions about effects were answered. You’ve learned both the State Hook and the Effect Hook, and there is a lot you can do with both of them combined. They cover most of the use cases for classes — and where they don’t, you might find the additional Hooks helpful.
At this point you might be questioning how Hooks work. How can React know which useState call corresponds to which state variable between re-renders? How does React “match up” previous and next effects on every update? On the next page we will learn about the Rules of Hooks — they’re essential to making Hooks work.