Möglichkeit, Werte aus einer Komponente direkt allen weiter unten im Dokumentenbaum liegenden Komponenten zur Verfügung zu stellen - ohne diese über jede Ebene übergeben zu müssen
Das Interface von Context kann sowohl Daten (aus dem State) als auch Eventhandler übergeben.
eine Anwendung kann viele verschiedene Kontexttypen haben, z.B.:
ThemeContext
LanguageContext
UserContext
TodosContext
eine Komponente weiter oben im Komponentenbaum kann ein Provider eines Kontexts sein
eine Komponente weiter unten im Komponentenbaum kann ein Consumer sein
(Datenfluss von oben nach unten, aber mit übersprungenen Zwischenebenen)
mögliche Struktur mit Providern, die selbst State verwalten:
Unterscheidung von Providern:
constate: Library, die einen Kontext mit zugehörigem State generieren kann
Definieren des Context:
selbst definierter Hook, der Todo-Daten verwaltet:
function useTodos() {
// ...
return { todos, addTodo, deleteTodo, setTodoCompleted };
}
erstellen einer Provider-Komponente und eines Consumer-Hooks:
const [TodosProvider, useTodosContext] = constate(useTodos);
"Providen" des Contexts:
function App() {
return (
<TodosProvider>
<AddTodoForm />
<TodoList />
<Statistics />
</TodosProvider>
);
}
Abfragen des Context:
function TodoList() {
const {
todos,
deleteTodo,
setTodoCompleted,
} = useTodosContext();
// ...
}
Schritte, um Context zur Verfügung zu stellen:
Schritte, um Context abzufragen:
useContext
in einer KomponenteContext-Definition in JavaScript:
// ThemeContext.js
import { createContext } from 'react';
// default value: null
const ThemeContext = createContext(null);
export { ThemeContext };
Ein Context hat immer einen Standard-/Fallback-Wert; dieser wird genutzt, wenn kein passender Provider gefunden wird
In TypeScript: Erstellen des Standard-Werts um den Typechecker zufrieden zu stellen kann mühsam sein
Definieren eines Context-Typs in TypeScript:
type ThemeContextType = {
theme: string;
onThemeChange: (theme: string) => void;
};
um den Typechecker zufrieden zu stellen:
tatsächliches Bereitstellen eines Standard-Werts:
const ThemeContext = createContext<ThemeContextType>({
theme: 'light',
onThemeChange: () => {},
});
verwenden von null
und Cast auf any:
const ThemeContext = createContext<ThemeContextType>(
null as any
);
mehr Informationen / Lösungen: React TypeScript cheatsheets
Beispiel: verwenden eines "reinen Providers" (State liegt in der App-Komponente)
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider
value={{ theme: theme, onThemeChange: setTheme }}
>
... sub-components ...
</ThemeContext.Provider>
);
}
Beispiel: Produkt-Seite mit einem "reinen" Context-Provider
function ProductPage() {
// ... (load product data from an API)
return (
<ProductContext.Provider value={productData}>
<ProductDescription />
<ProductPictures />
<ProductReviews />
<ProductQuestionsAndAnswers />
</ProductContext.Provider>
);
}
Beispiel: Erstellen eines Providers mit State, der State verwaltet und bereitstellt:
// TodosContext.tsx
function TodosProvider(props: { children: ReactNode }) {
const todosCtrl = useTodos();
<TodosContext.Provider value={todosCtrl}>
{props.children}
</TodosContext.Provider>;
}
function TodoApp() {
return <TodosProvider>...</TodosProvider>;
}
Context aus einer Komponente heraus abfragen:
const todosContext = useContext(TodosContext);