We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在一个经典的 React 应用中,组件之间通信是常用到的技术方案。在父子组件之间通常通过 props 来传递参数,而非父子组件就比较麻烦了,要么就一级一级通过 props 传递,要么就使用 Redux or Mobx 这类状态管理的状态管理库,但是这样无疑增加了应用的复杂度。在 FEers 的期盼中,React 团队终于从 16.3.0 版本开始新增了一个新的 API Context,福音啊。好了,今天我就来一起学习一下这个新的 Context。
React
props
Redux
Mobx
16.3.0
Context
Context 目的是为了共享可以被认为是 React 组件“全局”树的数据。例如当前应用的主题、首选语言等等。接下来看看通过 props 和 Context 两种方式实现按钮组件样式参数传递方式的对比:
class App extends React.Component { render() { return <Toolbar theme="dark" />; } } Toolbar(props) { return ( <div> <ThemedButton theme={props.theme} /> </div> ); } ThemedButton(props) { return <Button theme={props.theme} />; }
// 创建 context 实例 const ThemeContext = React.createContext('light'); class App extends React.Component { render() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } } Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } ThemedButton(props) { return ( <ThemeContext.Consumer> {theme => <Button {...props} theme={theme} />} </ThemeContext.Consumer> ); }
创建一个 Context ,React.createContext 提供了 {Provider,Comsumer} 两个方法,上面的代码也可以这个来写:
React.createContext
{Provider,Comsumer}
const {Provider,Comsumer} = React.createContext('light'); class App extends React.Component { render() { return ( <Provider value="dark"> {/* ... */} </Provider> ); } } {/* ... */} ThemedButton(props) { return ( <Consumer> {/* ... */} </Consumer> ); }
这里的 Provider 类似 react-redux 中的 Provider 组件,用来注入全局的 data (允许 Consumer 订阅 Context 的变化)。一个 Provider 可以连接到多个 Consumer。
Provider
react-redux
data
Consumer
Consumer 组件,表示要消费 Provider 传递的数据(订阅 Context 的响应组件)。当 Provider 发生变化的时候,所有的 Consumer 都会被 re-rendered。
re-rendered
新 Context 的引入,一定程度上可以减少不少项目对 redux 全家桶的依赖,从而降低了项目的复杂程度,何乐而不为呢~~
redux
The text was updated successfully, but these errors were encountered:
Sorry, something went wrong.
consumer 好像并没能订阅 context 的变化,只能获取初始值,是不是我用的不对? 我是这样用的: 在父组件:
import Child1 from './child1' const defaultContext = { a: 0, setA: function (a) { this.a = a } } export const Context = createContext() export default class Father extends React.Component { render() { return <Context.Provider value={defaultContext}> <Child1/> </Context.Provider> } }
在子组件:
class Child1 extends React.Component { render() { const {context} = this.props return<div style={{backgroundColor: '#897', padding: '29px'}}> 子组件1 <div>a:{context.a}</div> <input placeholder='输入' onChange={(e) => context.setA(e.target.value)}></input> </div> } } export default () => <Context.Consumer>{ (context) => { return <Child1 context={context}/> } }</Context.Consumer>
我在子组件中调用 context.setA() 修改了 context.a,但是子组件并没有更新
context.setA()
context.a
知道为啥子组件没有更新了,因为组件更新需要 state / props 变化,但是 context value 这两者都不是
No branches or pull requests
什么时候使用 Contsxt
Context 目的是为了共享可以被认为是
React
组件“全局”树的数据。例如当前应用的主题、首选语言等等。接下来看看通过props
和Context
两种方式实现按钮组件样式参数传递方式的对比:API
React.createContext
创建一个
Context
,React.createContext
提供了{Provider,Comsumer}
两个方法,上面的代码也可以这个来写:Provider
这里的
Provider
类似react-redux
中的Provider
组件,用来注入全局的data
(允许Consumer
订阅Context
的变化)。一个Provider
可以连接到多个Consumer
。Consumer
Consumer
组件,表示要消费Provider
传递的数据(订阅Context
的响应组件)。当Provider
发生变化的时候,所有的Consumer
都会被re-rendered
。结束语
新
Context
的引入,一定程度上可以减少不少项目对redux
全家桶的依赖,从而降低了项目的复杂程度,何乐而不为呢~~The text was updated successfully, but these errors were encountered: