#reactjs #next.js #react-context #context-api #use-reducer
#reactjs #next.js #реагировать-контекст #используйте-reducer
Вопрос:
Я обнаружил, что в официальном next.js пример, state
и dispatch
были помещены информационные отдельные поставщики контекста.
Какой смысл был в этом? Предотвращает ли эта практика ненужные повторные рендеринги?
export const CounterProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, 0)
return (
<CounterDispatchContext.Provider value={dispatch}>
<CounterStateContext.Provider value={state}>
{children}
</CounterStateContext.Provider>
</CounterDispatchContext.Provider>
)
}
export const useCount = () => useContext(CounterStateContext)
export const useDispatchCount = () => useContext(CounterDispatchContext)
Ответ №1:
Вам не нужно помещать их в отдельные ContextProviders, если почти все ваши компоненты используют как состояние, так и отправку, просто убедитесь, что вы запоминаете аргумент, который вы передаете значению поставщика, когда вы передаете их как объект. Таким образом, ваши потребители будут повторно отображать только тогда, когда состояние действительно изменится. Также обратите внимание, что dispatch
экземпляр фактически не изменяется, поэтому нет смысла создавать для него отдельный контекст
export const CounterProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, 0)
const contextValue = useMemo(() => ({state, dispatch}), [state, dispatch])
return (
<CounterContext.Provider value={contextValue}>
{children}
</CounterContext.Provider>
)
}
Редактировать:
Как указал @dciccale в комментариях, имеет смысл сохранять отправку и состояние в отдельных контекстах, если в вашем приложении довольно много компонентов, которые в основном используют только отправку, и, следовательно, они не будут повторно отображаться при изменении состояния.
Даже если мы запоминаем contextValue
с помощью useMemo hook, contextValue
он все равно будет переоцениваться каждый раз, когда мы обновляем state
значение, в результате чего все компоненты, зависящие от контекста, будут повторно отображаться, даже некоторые из них зависят только от dispatch
only .
Смотрите также: https://hswolff.com/blog/how-to-usecontext-with-usereducer/#performance-concerns
Оцените требования к вашему приложению и примите разумное решение.
Комментарии:
1. Есть ли какая-либо выгода от наличия двух отдельных поставщиков контекста? Или это просто next.js авторы переоценили свой пример?
2. Разделение контекста имеет преимущество, когда контекст хранит информацию о совершенно разных вещах, в приведенном выше случае это не требуется и не служит специальной цели
3. Я не могу найти никакого руководства по разделению контекста в Google. Можете ли вы объяснить подробнее?
4. Я думаю, что это имеет значение, создавая отдельного поставщика контекста для состояния и для отправки. Если у вас есть дочерние компоненты, которым требуется только функция отправки, а не состояние, эти компоненты также будут повторно отображаться, если состояние поставщика изменилось. однако, если существуют отдельные поставщики контекста, один для состояния и один для отправки, дочерним компонентам, использующим только отправку, не нужно будет повторно отображать при изменении состояния.