阅读 91

React Context & useContext 学习笔记

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….

文章分类
前端
文章标签