Ich habe die Spracheinstellungen im Kontext wie unten
class LanguageProvider extends Component {
static childContextTypes = {
langConfig: PropTypes.object,
};
getChildContext() {
return { langConfig: 'en' };
}
render() {
return this.props.children;
}
}
export default LanguageProvider;
Mein Bewerbungscode lautet wie folgt
<LanguageProvider>
<App>
<MyPage />
</App>
</LanguageProvider>
Meine Seite enthält eine Komponente zum Wechseln der Sprache
<MyPage>
<LanguageSwitcher/>
</MyPage>
LanguageSwitcher
In diesem MyPage
Fall muss der Kontext aktualisiert werden, um die Sprache wie unten beschrieben in 'jp' zu ändern
class LanguageSwitcher extends Component {
static contextTypes = {
langConfig: PropTypes.object,
};
updateLanguage() {
//Here I need to update the langConfig to 'jp'
}
render() {
return <button onClick={this.updateLanguage}>Change Language</button>;
}
}
export default LanguageSwitcher;
Wie kann ich den Kontext innerhalb der LanguageSwitcher-Komponente aktualisieren?
javascript
reactjs
react-context
mshameer
quelle
quelle
Antworten:
Haken verwenden
Hooks wurden in 16.8.0 eingeführt, sodass für den folgenden Code eine Mindestversion von 16.8.0 erforderlich ist (scrollen Sie nach unten, um das Beispiel für Klassenkomponenten anzuzeigen). CodeSandbox-Demo
1. Festlegen des übergeordneten Status für den dynamischen Kontext
Um einen dynamischen Kontext zu haben, der an die Verbraucher weitergegeben werden kann, verwende ich zunächst den Status der Eltern. Dies stellt sicher, dass ich eine einzige Quelle der Wahrheit habe. Zum Beispiel sieht meine übergeordnete App folgendermaßen aus:
const App = () => { const [language, setLanguage] = useState("en"); const value = { language, setLanguage }; return ( ... ); };
Das
language
ist im Zustand gespeichert. Wir werden beidelanguage
und die Setter-FunktionsetLanguage
später über den Kontext übergeben.2. Erstellen eines Kontexts
Als nächstes habe ich einen Sprachkontext wie folgt erstellt:
// set the defaults const LanguageContext = React.createContext({ language: "en", setLanguage: () => {} });
Hier setze ich die Standardeinstellungen für
language
('en') und einesetLanguage
Funktion, die vom Kontextanbieter an die Verbraucher gesendet wird. Dies sind nur Standardeinstellungen, und ich werde ihre Werte angeben, wenn die Anbieterkomponente im übergeordneten Element verwendet wirdApp
.Hinweis: Das
LanguageContext
bleibt gleich, ob Sie3. Erstellen eines Kontextkonsumenten
Damit der Sprachumschalter die Sprache einstellen kann, sollte er über den Kontext Zugriff auf die Spracheinstellungsfunktion haben. Es kann ungefähr so aussehen:
const LanguageSwitcher = () => { const { language, setLanguage } = useContext(LanguageContext); return ( <button onClick={() => setLanguage("jp")}> Switch Language (Current: {language}) </button> ); };
Hier setze ich nur die Sprache auf 'jp', aber Sie haben möglicherweise Ihre eigene Logik, um Sprachen dafür festzulegen.
4. Einwickeln des Verbrauchers in einen Anbieter
Jetzt werde ich meine Sprachumschaltkomponente in a rendern
LanguageContext.Provider
und die Werte, die über den Kontext gesendet werden müssen, an eine tiefere Ebene übergeben. So sehen meine ElternApp
aus: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> ); };
Wenn Sie jetzt auf den Sprachumschalter klicken, wird der Kontext dynamisch aktualisiert.
CodeSandbox-Demo
Klassenkomponenten verwenden
Die neueste Kontext-API wurde in React 16.3 eingeführt und bietet eine hervorragende Möglichkeit, einen dynamischen Kontext zu erstellen. Der folgende Code erfordert eine Mindestversion von 16.3.0. CodeSandbox-Demo
1. Festlegen des übergeordneten Status für den dynamischen Kontext
Um einen dynamischen Kontext zu haben, der an die Verbraucher weitergegeben werden kann, verwende ich zunächst den Status der Eltern. Dies stellt sicher, dass ich eine einzige Quelle der Wahrheit habe. Zum Beispiel sieht meine übergeordnete App folgendermaßen aus:
class App extends Component { setLanguage = language => { this.setState({ language }); }; state = { language: "en", setLanguage: this.setLanguage }; ... }
Das
language
wird im Status zusammen mit einer Sprachsetzermethode gespeichert, die Sie möglicherweise außerhalb des Statusbaums aufbewahren.2. Erstellen eines Kontexts
Als nächstes habe ich einen Sprachkontext wie folgt erstellt:
// set the defaults const LanguageContext = React.createContext({ language: "en", setLanguage: () => {} });
Hier setze ich die Standardeinstellungen für
language
('en') und einesetLanguage
Funktion, die vom Kontextanbieter an die Verbraucher gesendet wird. Dies sind nur Standardeinstellungen, und ich werde ihre Werte angeben, wenn die Anbieterkomponente im übergeordneten Element verwendet wirdApp
.3. Erstellen eines Kontextkonsumenten
Damit der Sprachumschalter die Sprache einstellen kann, sollte er über den Kontext Zugriff auf die Spracheinstellungsfunktion haben. Es kann ungefähr so aussehen:
class LanguageSwitcher extends Component { render() { return ( <LanguageContext.Consumer> {({ language, setLanguage }) => ( <button onClick={() => setLanguage("jp")}> Switch Language (Current: {language}) </button> )} </LanguageContext.Consumer> ); } }
Hier setze ich nur die Sprache auf 'jp', aber Sie haben möglicherweise Ihre eigene Logik, um Sprachen dafür festzulegen.
4. Einwickeln des Verbrauchers in einen Anbieter
Jetzt werde ich meine Sprachumschaltkomponente in a rendern
LanguageContext.Provider
und die Werte, die über den Kontext gesendet werden müssen, an eine tiefere Ebene übergeben. So sehen meine ElternApp
aus: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> ); } }
Wenn Sie jetzt auf den Sprachumschalter klicken, wird der Kontext dynamisch aktualisiert.
CodeSandbox-Demo
quelle
Provider
?value
, werden die Standardeinstellungen vom Verbraucher verwendet.setLanguage: (language: string) => {}
funktioniert bei mir.Die obige Antwort von Maithani ist eine großartige Lösung, aber das ist eine Klassenkomponente ohne die Verwendung von Haken. Da es von React empfohlen wird, funktionale Komponenten und Hooks zu verwenden , werde ich es mit useContext- und useState-Hooks implementieren. So können Sie den Kontext innerhalb einer untergeordneten Komponente aktualisieren.
LanguageContextMangement.js
import React, { useState } from 'react' export const LanguageContext = React.createContext({ language: "en", setLanguage: () => {} }) export const LanguageContextProvider = (props) => { const setLanguage = (language) => { setState({...state, language: language}) } const initState = { language: "en", setLanguage: setLanguage } const [state, setState] = useState(initState) return ( <LanguageContext.Provider value={state}> {props.children} </LanguageContext.Provider> ) }
App.js.
import React, { useContext } from 'react' import { LanguageContextProvider, LanguageContext } from './LanguageContextManagement' function App() { const state = useContext(LanguageContext) return ( <LanguageContextProvider> <button onClick={() => state.setLanguage('pk')}> Current Language is: {state.language} </button> </LanguageContextProvider> ) } export default App
quelle
() => {}
state.setLanguage('pk')
nichts getan wird, daconst state = useContext(LanguageContext)
es außerhalb desLanguageContextProvider
. Ich habe mein Problem gelöst, indem ich den Anbieter um eine Ebene nach oben verschoben und dannuseContext
für ein Kind eine Ebene darunter verwendet habe.<LanguageContext.Consumer> {value => /* access your value here */} </LanguageContext.Consumer>
.Eine recht einfache Lösung besteht darin, den Status in Ihrem Kontext festzulegen, indem Sie eine setState-Methode wie folgt in Ihren Provider aufnehmen:
return ( <Context.Provider value={{ state: this.state, updateLanguage: (returnVal) => { this.setState({ language: returnVal }) } }}> {this.props.children} </Context.Provider> )
Rufen Sie bei Ihrem Verbraucher updateLanguage folgendermaßen auf:
// button that sets language config <Context.Consumer> {(context) => <button onClick={context.updateLanguage({language})}> Set to {language} // if you have a dynamic val for language </button> <Context.Consumer>
quelle