Komponent useContext umożliwia przekazywanie danych wewnątrz drzewa komponentów bez konieczności przekazywania ich przez właściwości każdego komponentu pośredniego. Dzięki temu możliwe jest współdzielenie pewnych wartości przez takie komponenty bez konieczności przekazywania ich jako właściwości na każdym poziomie drzewa.
Hook useContext jest przydatny do udostępniania danych, które można uznać za „globalne” dla drzewa komponentów React. Stwórzmy jeden:
const DataContext = createContext();
const DataContextProvider = (props) => {
const [data, setData] = useReducer(switchData, {
color: "gray",
isTextVisible: false,
})
return (
<DataContext.Provider value={{data, setData}} >
{props.children}
</DataContext.Provider>
)
}
W powyższym przykładzie utworzyliśmy nowy kontekst (funkcja createContext) i opakowaliśmy zwracane dane z komponentu DataContextProvider w komponencie Provider, który umożliwia komponentom dzieciom korzystanie z danych kontekstu. Innymi słowy – wszystkie komponenty opakowane przez komponent Provider mają dostęp do danych w kontekście (w tym przypadku: zmienna data i funkcja setData).
Dodajmy więcej kodu: funkcję swithData i eksport komponentu DataContextProvider, a cały komponent dataContext będzie wyglądał następująco:
dataContext.js:
import React, { createContext, useReducer } from 'react';
export const DataContext = createContext();
const switchData = (state, action) => {
switch (action.type) {
case "changeColor":
return {...state, color: action.color};
case "changeTextVisibility":
return {...state, isTextVisible: !state.isTextVisible};
default:
return state;
}
}
const DataContextProvider = (props) => {
const [data, setData] = useReducer(switchData, {
color: "gray",
isTextVisible: false,
})
return (
<DataContext.Provider value={{data, setData}} >
{props.children}
</DataContext.Provider>
)
}
export default DataContextProvider;
Kiedy tworzymy kontekst za pomocą hook-a useContext, musimy opakować w niego wszystkie komponenty, które mają korzystać z danych z kontekstu. Dlatego dodajemy do naszego komponentu App.js ten kod:
App.js:
import React from 'react';
import HookExample from './components/hookExample.js';
import DataContextProvider from './contexts/dataContext.js';
function App() {
return (
<DataContextProvider >
<HookExample />
</DataContextProvider>
);
}
export default App;
Teraz możemy wykorzystać nasze dane kontekstowe w innych komponentach:
HookExample.js:
import React, { useContext } from 'react';
import { DataContext } from '../contexts/dataContext.js';
const HookExample = () => {
const dataContext = useContext(DataContext);
return (
<div className="App">
<p style={{color: dataContext.data.color}}>This is sample text</p>
<div style={{display: dataContext.data.isTextVisible ? "block" : "none"}}>
This is more text, which is visible if clicked on "Show more text" button
</div>
<div>
<button onClick={() => dataContext.setData({type: "changeColor", color: 'red'})}>Change text color</button>
<button onClick={() => dataContext.setData({type: "changeTextVisibility"})}>Show more text</button>
</div>
</div>
);
}
export default HookExample;
W komponencie HookExample wykorzystaliśmy dane (zmienne data.color, data.isTextVisible i funkcja setData) pobrane z komponentu dataContext, w którym stworzyliśmy kontekst. W ten sam sposób możemy wykorzystać te dane w innych komponentach, jeśli są one opakowane w komponent DataContextProvider (który zwraca nasz kontekst).
Zobacz DEMO i sprawdź, jak działa hook useContext
Kod do tego postu możesz naleźć tu: https://github.com/love-coding-pl/React-Hooks-Examples/tree/Hook-3-useContext