Korzystanie z haków
Hooki zostały wprowadzone w 16.8.0, więc poniższy kod wymaga minimalnej wersji 16.8.0 (przewiń w dół, aby zobaczyć przykład komponentów klas). CodeSandbox Demo
1. Ustawienie stanu nadrzędnego dla dynamicznego kontekstu
Po pierwsze, aby mieć dynamiczny kontekst, który można przekazać konsumentom, użyję stanu rodzica. Gwarantuje to, że mam jedno źródło prawdy. Na przykład moja aplikacja nadrzędna będzie wyglądać następująco:
const App = () => {
const [language, setLanguage] = useState("en");
const value = { language, setLanguage };
return (
...
);
};
language
Jest przechowywana w państwie. Później przekażemy obie language
funkcje i funkcję ustawiającą setLanguage
przez kontekst.
2. Tworzenie kontekstu
Następnie stworzyłem taki kontekst językowy:
const LanguageContext = React.createContext({
language: "en",
setLanguage: () => {}
});
Tutaj ustawiam wartości domyślne dla language
(„en”) i setLanguage
funkcję, która zostanie wysłana przez dostawcę kontekstu do konsumenta (ów). Są to tylko wartości domyślne i podam ich wartości, gdy używam komponentu dostawcy w obiekcie nadrzędnym App
.
Uwaga: LanguageContext
pozostaje to samo, niezależnie od tego, czy używasz haków, czy komponentów opartych na klasach.
3. Stworzenie konsumenta kontekstowego
Aby przełącznik języka ustawiał język, powinien mieć dostęp do funkcji ustawiania języka poprzez kontekst. Może wyglądać mniej więcej tak:
const LanguageSwitcher = () => {
const { language, setLanguage } = useContext(LanguageContext);
return (
<button onClick={() => setLanguage("jp")}>
Switch Language (Current: {language})
</button>
);
};
Tutaj ustawiam język na „jp”, ale możesz mieć własną logikę, aby ustawić języki.
4. Owinięcie konsumenta w dostawcę
Teraz wyrenderuję mój komponent do przełączania języków w a LanguageContext.Provider
i przekażę wartości, które muszą być wysłane przez kontekst do dowolnego poziomu głębiej. Oto jak wygląda mój rodzic App
:
const App = () => {
const [language, setLanguage] = useState("en");
const value = { language, setLanguage };
return (
<LanguageContext.Provider value={value}>
<h2>Current Language: {language}</h2>
<p>Click button to change to jp</p>
<div>
{/* Can be nested */}
<LanguageSwitcher />
</div>
</LanguageContext.Provider>
);
};
Teraz po każdym kliknięciu przełącznika języka dynamicznie aktualizuje on kontekst.
CodeSandbox Demo
Korzystanie z komponentów klas
Najnowsze API kontekstowe zostało wprowadzone w React 16.3, co zapewnia doskonały sposób na posiadanie dynamicznego kontekstu. Poniższy kod wymaga minimalnej wersji 16.3.0. CodeSandbox Demo
1. Ustawienie stanu nadrzędnego dla dynamicznego kontekstu
Po pierwsze, aby mieć dynamiczny kontekst, który można przekazać konsumentom, użyję stanu rodzica. Gwarantuje to, że mam jedno źródło prawdy. Na przykład moja aplikacja nadrzędna będzie wyglądać następująco:
class App extends Component {
setLanguage = language => {
this.setState({ language });
};
state = {
language: "en",
setLanguage: this.setLanguage
};
...
}
Plik language
on przechowywany w stanie wraz z metodą ustawiania języka, którą można trzymać poza drzewem stanu.
2. Tworzenie kontekstu
Następnie stworzyłem taki kontekst językowy:
const LanguageContext = React.createContext({
language: "en",
setLanguage: () => {}
});
Tutaj ustawiam wartości domyślne dla language
(„en”) i setLanguage
funkcję, która zostanie wysłana przez dostawcę kontekstu do konsumenta (ów). Są to tylko wartości domyślne i podam ich wartości, gdy używam komponentu dostawcy w obiekcie nadrzędnym App
.
3. Stworzenie konsumenta kontekstowego
Aby przełącznik języka ustawiał język, powinien mieć dostęp do funkcji ustawiania języka poprzez kontekst. Może wyglądać mniej więcej tak:
class LanguageSwitcher extends Component {
render() {
return (
<LanguageContext.Consumer>
{({ language, setLanguage }) => (
<button onClick={() => setLanguage("jp")}>
Switch Language (Current: {language})
</button>
)}
</LanguageContext.Consumer>
);
}
}
Tutaj ustawiam język na „jp”, ale możesz mieć własną logikę, aby ustawić języki.
4. Owinięcie konsumenta w dostawcę
Teraz wyrenderuję mój komponent do przełączania języków w a LanguageContext.Provider
i przekażę wartości, które muszą być wysłane przez kontekst do dowolnego poziomu głębiej. Oto jak wygląda mój rodzic App
:
class App extends Component {
setLanguage = language => {
this.setState({ language });
};
state = {
language: "en",
setLanguage: this.setLanguage
};
render() {
return (
<LanguageContext.Provider value={this.state}>
<h2>Current Language: {this.state.language}</h2>
<p>Click button to change to jp</p>
<div>
{/* Can be nested */}
<LanguageSwitcher />
</div>
</LanguageContext.Provider>
);
}
}
Teraz po każdym kliknięciu przełącznika języka dynamicznie aktualizuje on kontekst.
CodeSandbox Demo