1. Context
Context主要用于解决多层级组件嵌套时,数据传递的问题。
Context设计目的是为了共享那些对于一个组件树而言是“全局”的数据。
使用Context需要考虑的问题是:使得组件的复用性变差。
1.1 使用示例
demo
├── myContext.js # context 对象
├── myComponent.js # 子组件
└── app.js # 根组件
myContext.js
export const langList = {
en: { text: 'BUTTON' },
zh: { text: '按钮' }
};
export const MyContext = React.createContext({
lang: langList.en, // 默认值
onChange: () => {}, // 修改context默认函数
});
myComponent.js
import { MyContext, langList } from './myContext';
class MyComponent extends React.Component {
render() {
let props = this.props;
let data = this.context;
return (
<button
{...props}
// 可以调用传入的onChange方法修改context
onClick={() => data.onChange(langList.en)}>
{data.lang.text}
</button>
);
}
}
// 保证可以渲染默认值
// 未提供Provider value时将渲染默认值
MyComponent.contextType = MyContext;
export default MyComponent;
函数式组件可以使用Context.ConsumerAPI:
myComponent.js
import { MyContext, langList } from './myContext';
function MyComponent(props) {
return (
<MyContext.Consumer>
{
data => (
<button
{...props}
onClick={() => data.onChange(langList.en)}>
{data.lang.text}
</button>
)
}
</MyContext.Consumer>
);
}
app.js
import { MyContext, langList } from './myContext';
import MyComponent from './myComponent';
class App extends React.Component {
// 根组件的context修改方法
this.onChange = (lang) => {
this.setState({ lang });
};
state = {
value: {
lang: langList.zh,
onChange: this.onChange,
}
};
render() {
return (
// 注意不要直接在这里赋值对象
// 因为每次render都是新的对象 都会触发consumer意外的渲染
// <MyContext.Provider value={{ lang: this.state.lang, onChange: this.onChange }}>
// 应该放在state中
<MyContext.Provider value={this.state.value}>
// 为了简单这里就不嵌套中间组件了
// 实际这里可以随意嵌套组件
<MyComponent />
</MyContext.Provider>
);
}
}
ReactDOM.render(<App />, document.root);
1.2 多 Context 使用
根组件嵌套Context.Provider,子组件中嵌套Context.Provider即可。
2. useContext
解决了在函数式组件中方便使用Context,不用Context.ConsumerAPI。
接收一个context对象(React.createContext的返回值)并返回该context的当前值。
const value = useContext(MyContext);
调用了useContext的组件总会在context值变化时重新渲染。
import { MyContext } from './myContext';
function MyComponent(props) {
const data = useContext(MyContext);
return (
<button
{...props}>
{data.lang.text}
</button>
);
}
The End. Reference zh-hans.reactjs.org/docs/contex….