11 апреля 2025 г. (изменено: 11 апреля 2025 г.)
Канал: @cherkashindev
⚛️ State is tied to a position in the render tree
Помнится в одном из своих пет проектов у меня был баг — при переходе между страницами у меня не пересоздавался zustand стор из-за чего компонент PersonalStatistic использовал стор компонента CodeReviewCharts 👇
children: [
{
path: '/charts',
element: (
<ChartsStoreProvider createStore={createPersonalPageStore}>
<CodeReviewCharts />
</ChartsStoreProvider>
),
},
{
path: '/personal',
element: (
<ChartsStoreProvider createStore={createCommonChartsStore}>
<PersonalStatistic />
</ChartsStoreProvider>
),
},
]Дело было в том, что контекст был одним и тем же компонентом ChartsStoreProvider. Тогда я просто добавил key для сторов и проблема ушла.
children: [
{
path: '/charts',
element: (
<ChartsStoreProvider key="charts" /*👈*/ createStore={createPersonalPageStore}>
<CodeReviewCharts />
</ChartsStoreProvider>
),
},
{
path: '/personal',
element: (
<ChartsStoreProvider key="personal" /*👈*/ createStore={createCommonChartsStore}>
<PersonalStatistic />
</ChartsStoreProvider>
),
},
]Не помню было ли это в старой документации реакта, но в новой явно сказано:
State is tied to a position in the render tree
Состояние привязано к определённой позиции в дереве рендера.
То, есть проблема была в том, что при переходе на страницу /personal, ChartsStoreProvider оставался на той же позиции в дереве и поэтому использовался “неподходящий” стейт предыдущего провайдера.
Раньше я думал, что стейт живет “внутри компонента” — то, есть связан с инстансом конкретного компонента, как свойста в классе. Но документация явно говорит:
When you give a component state, you might think the state “lives” inside the component. But the state is actually held inside React. React associates each piece of state it’s holding with the correct component by where that component sits in the render tree.
Когда вы добавляете состояние (state) компоненту, может показаться, что это состояние «находится» внутри самого компонента. Однако на самом деле состояние хранится внутри React. React сопоставляет каждую единицу состояния с нужным компонентом, исходя из того, где этот компонент находится в дереве рендера.
Вот тут в демке это наглядно видно.
А ещё key можно использовать чтобы явно перерендерить компонент, если у него есть какой-то внутренний стейт.