Рефакторинг вашего компонента контекста и устранение запутанного доступа к данным
В реакции мы передаем данные/функции от родителя к дочернему. Таким образом, если у родителя есть какие-то данные/функция, которые нужны дочернему элементу на каком-то глубоком уровне, мы должны передать его в качестве реквизита через каждый компонент на пути от родителя к предполагаемому дочернему элементу. Используйте встроенный в реакцию хук useContext, чтобы решить эту проблему.
Хук React useContext() помогает легко передавать данные любым дочерним элементам на любой глубине. По сути, есть 2 шага —
- Создайте Provider, передайте значения, к которым вы хотите получить доступ,и оберните ими родительский компонент.
- Используйте хук useContext() для доступа к переданным значениям дочернего элемента на любой глубине родителя.
Умный способ — реорганизовать коды, связанные с контекстом, в отдельную папку context, которая содержит все контексты, используемые в приложении. В каждом компоненте внутри папки context создайте контекст (можно также экспортировать настраиваемый хук для доступа к данным) и экспортируйте поставщика. Вот как должен выглядеть пример ThemeProvider (context/ThemeContext.js):
import { createContext, useContext } from 'react' const ThemeContext = createContext() export const useTheme = () => useContext(ThemeContext) export default function ThemeProvider({ children }) { const [theme, setTheme] = useState('dark') return ( <ThemeContext.Provider value={{ theme, setTheme }}> {children} </ThemeContext.Provider> ) }
Теперь предположим, что мы хотим, чтобы все дочерние элементы компонента _app использовали эту тему и setTheme. Итак, наш родительский компонент — это _app, там —
import ThemeProvider from 'context/ThemeContext' export default function App() { return ( <ThemeProvider> // child components here </ThemeProvider> ) }
И в любом дочернем компоненте на любой глубине, когда мы хотим использовать либо theme, либо setTheme, мы можем просто использовать хук useTheme(), например —
import { useTheme } from 'context/ThemeContext' export default function ChildComponentXY() { const { theme, setTheme } = useTheme() // ... rest of the component codes }
Таким образом, мы можем иметь несколько провайдеров контекста внутри приложения, все они рефакторинг и разделены на красивую папку с именем context.