使用钩子
钩子是在16.8.0中引入的,因此下面的代码需要16.8.0的最低版本(向下滚动查看类组件示例)。CodeSandbox演示
1. 为动态上下文设置父状态
首先,为了有一个可以传递给消费者的动态上下文,我将使用父节点的状态。这确保了我有一个唯一的真相来源。例如,我的父App看起来是这样的:
const App = () => {
const [language, setLanguage] = useState("en");
const value = { language, setLanguage };
return (
...
);
};
语言存储在状态中。稍后我们将通过上下文传递language和setter函数setLanguage。
2. 创建上下文
接下来,我创建了一个像这样的语言上下文:
// set the defaults
const LanguageContext = React.createContext({
language: "en",
setLanguage: () => {}
});
这里我设置了language ('en')的默认值和一个setLanguage函数,该函数将由上下文提供者发送给消费者。这些只是默认值,我将在父应用程序中使用提供者组件时提供它们的值。
注意:无论使用钩子还是基于类的组件,LanguageContext都保持不变。
3.创建上下文使用者
为了让语言切换器设置语言,它应该能够通过上下文访问语言设置器函数。它可以看起来像这样:
const LanguageSwitcher = () => {
const { language, setLanguage } = useContext(LanguageContext);
return (
<button onClick={() => setLanguage("jp")}>
Switch Language (Current: {language})
</button>
);
};
这里我只是将语言设置为“jp”,但您可能有自己的逻辑来为此设置语言。
4. 将使用者包装在提供者中
现在我将在LanguageContext中呈现我的语言切换器组件。提供程序,并传入必须通过上下文发送到任何更深层次的值。这是我的父应用程序的样子:
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>
);
};
现在,无论何时单击语言切换器,它都会动态更新上下文。
CodeSandbox演示
使用类组件
最新的上下文API是在React 16.3中引入的,它提供了一种拥有动态上下文的好方法。下面的代码需要16.3.0的最低版本。CodeSandbox演示
1. 为动态上下文设置父状态
首先,为了有一个可以传递给消费者的动态上下文,我将使用父节点的状态。这确保了我有一个唯一的真相来源。例如,我的父App看起来是这样的:
class App extends Component {
setLanguage = language => {
this.setState({ language });
};
state = {
language: "en",
setLanguage: this.setLanguage
};
...
}
语言与语言设置方法一起存储在状态中,您可以将其保存在状态树之外。
2. 创建上下文
接下来,我创建了一个像这样的语言上下文:
// set the defaults
const LanguageContext = React.createContext({
language: "en",
setLanguage: () => {}
});
这里我设置了language ('en')的默认值和一个setLanguage函数,该函数将由上下文提供者发送给消费者。这些只是默认值,我将在父应用程序中使用提供者组件时提供它们的值。
3.创建上下文使用者
为了让语言切换器设置语言,它应该能够通过上下文访问语言设置器函数。它可以看起来像这样:
class LanguageSwitcher extends Component {
render() {
return (
<LanguageContext.Consumer>
{({ language, setLanguage }) => (
<button onClick={() => setLanguage("jp")}>
Switch Language (Current: {language})
</button>
)}
</LanguageContext.Consumer>
);
}
}
这里我只是将语言设置为“jp”,但您可能有自己的逻辑来为此设置语言。
4. 将使用者包装在提供者中
现在我将在LanguageContext中呈现我的语言切换器组件。提供程序,并传入必须通过上下文发送到任何更深层次的值。这是我的父应用程序的样子:
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>
);
}
}
现在,无论何时单击语言切换器,它都会动态更新上下文。
CodeSandbox演示