阅读量:0
一、React Context 原理
简单地说就是可以将一些数据注入到Context对象中,使其下辖的组件可以随时随地访问这些数据,省去了逐层传递的步骤。
相对于在组件里挖槽(比如{props.children}),使用Context应该更注重随时随地都可能有需求使用这些数据这个目的。
核心API:
- React.createContext(defaultValue)
创建Context对象,可传入defaultValue或undefined。 即:当某个组件订阅了Context但未匹配到Provider时,就会访问defaultValue值,当传入undefined时,defaultValue无效。(defaultValue永远不会发生改变。当 React 无法找到匹配的 provider 时,该值会被作为后备方案。)- Context.Provider
Context对象都会返回Provider组件,其下的组件会订阅Provider中的数据。Provider接收value属性,用于将value传递给消费组件,当value发生变化时所有消费组件都会重新渲染。
二、使用
// AppContext.js import React from 'react'; const defaultValue = null const AppContext = React.createContext(defaultValue); export default AppContext;
// app.ts import AppContext from './appContext'; class App extends Component<any, any> { state: any = { baseConfig: {value: 123} } //要渲染的页面 render() { return ( <AppContext.Provider value={this.state.baseConfig}> {this.props.children} </AppContext.Provider> ) } } export default App
// 自组件使用 export function Component(props: any) { return <AppContext.Consumer> { (value) => <Customer_page_overview_data {...props} {...value} /> } </AppContext.Consumer> }
三、异步传递问题
异步获取的数据存储全局的context中,子组件中使用这个context的数据时,数据为空;
解决:
在 componentDidUpdate方法里异步获取数据;
每次this.setState()都会触发componentDidUpdate这个方法。因此我们在componentDidUpdate 中使用 this.setState() 就会无限循环。所以我们使用if来进行控制。
// app.ts import AppContext from './appContext'; class App extends Component<any, any> { state: any = { baseConfig: {value: 123} } componentDidUpdate() { if (!this.state.baseConfig.value) { API_CONFIG.getLogo({queryParams: {var: "report.baseConfig.target"}}).then(baseConfig => { console.log(baseConfig, "-=-=--=-=-AppContext=-=-=-=") this.setState({baseConfig}) }) } } //要渲染的页面 render() { return ( <AppContext.Provider value={this.state.baseConfig}> {this.props.children} </AppContext.Provider> ) } } export default App