React 新 Context API
它更符合工程化, 不再是实验性的,” 现在它是一流的API! 并且它还使用了 RENDER PROP!
注意: 大家可以通过 newsletter获取我最新的资讯.我发送每封电子邮件两周后发布到 我的博客 . 订阅即可在收件箱中获得更早更多的内容!
你在react官网上听说过 context API?如果你听说过, 你会像许多人那样,因为看过官网的文档,而害怕直接使用它么:
该搜索结果第一个显示“为何不用使用Context”.不会激发对context API.的大量信心 .为了使事情更加受关注,搜索结果这部分说:
如果你想让你的应用更稳定,别使用context。因为这是一个实验性的API,在未来的React版本中可能会被更改。.
那么你为何要使用context?
你有没有经历过尝试在react状态树中从底部组建向顶部组建获取状态值的痛苦? 这种痛苦称作“prop drilling” 并且 是让人感到崩溃的. 最终你必须通过不关心数据的组件来传递props,以便将这些props发送给需要关心这些数据的组件。 并且随着你移到这些组建这些痛苦将被扩大。
实际上你可以使用常规的JavaScript模块来避免这些问题。你可以把这些数据放在一个单独的模块中,这样你就可以随时随地的导入或者访问相关数据。 但是,在更新的时候会遇到一些麻烦 (你必须实现一个方法来保证实时更新), 并且服务器端的渲染也可能对单例有 问题 。
如此,这就需要 redux这种状态管理库参与进来的地方了 . redux允许您轻松地从store(状态树)中的任何位置获取数据.你所要做的就是使用这个叫做 <Provider />
用法,的东西,神奇的是你的store(状态树)可以被任何“连接”的组件所访问
如果我告诉你 Redux用法之 <Provider />
正在使用context的特性,那该怎么办?确实是这样! provider组件将数据放入context中,并且“连接”高阶组件将数据从context中提取出来。 因此,实际上,Redux并不允许您的数据在任何地方访问......context是就是这样!
那么,为什么你应该使用context? 那么,你可能早已经爱上了它了 !即使你不直接使用context, 但是你的app已经通过react-redux
,MobX-react
,react-router
,glamorous
等来使用它!
Context的重生
所以我们爱上了context
, 但是要记住官方的警告“它又可能在之后的react版本中被摒弃掉? 现在context正式发布了! 你将会喜欢上它!
在一个月以前, the React团队从 Yarn, Rust, 和 Ember 的 rfcs 仓库中受到了启发,创建了一个新的自己的RFCs 仓库 . 第一个从仓库拉代码的是 Andrew Clark (react核心团队成员) 它被称为“新版的 context”.其中, Andrew 描述了新版的context 将会是什么样的. 在这仓库里有些很有趣的讨论。 几天后, Andrew 就向 React 仓库提了一个“New context API”的PR.
所以呢它看起来怎么样?肉眼估计新的 API 与之前的 API 存在百万级别的差异. 这是我做的一个简单实用的: 实例
这是一个更简单的版本,所以你不必另外打开代码链接:
const ThemeContext = React.createContext('light')class ThemeProvider extends React.Component { state = {theme: 'light'} render() { return ( `<ThemeContext.Provider value={this.state.theme}>` {this.props.children} `</ThemeContext.Provider>` ) } }class App extends React.Component { render() { return ( `<ThemeProvider>` `<ThemeContext.Consumer>` {val => `<div>`{val}`</div>`} `</ThemeContext.Consumer>` `</ThemeProvider>` ) } }
在我的代码例子中你或许注意到了, 我正在使用render prop Consumer组件(最好!), 如果你不喜欢用这种方式, 您可以使用 context API (这就是为什么它是最好的)轻松实现更高阶组件或其他内容 最新的 context API 由3个主要部分组成:
React.createContext
用于传递初始值(可选择 a fancy opt-out function that uses a bitmask). ,返回一个包含 provider 和 consumer 的对象The
Provider
组件在树中内更深层次的值,并接受一个名为值的prop(可以是任何东西)。.The
Consumer
函数在 provider 之后任何地方使用,并传递一个返回 JSX 的函数.
我对这个 API 充满了期待.React 团队 也将会移除 context 是实验性 API 的警告,因为,它现在是框架 “一级棒的特性” . 这就意味着开发者不要再担心使用 context 来解决应用中 prop-drilling 的问题了,对 Redux 也将不再那么依赖,对 React 将更加喜欢 (或许 James Kyle的 Unstated 是我们一直所期待的).
我最近 看到的:
我认为,如果我们能避免过早和任意打断 render 方法,那么我们就更少的会感受到这种痛苦。但是,即使我们感受到了,我们也有一个坚实的核心 React API来帮助我们避免这个问题。
Context 实践
我多次遇见一个关于 context API (或普通的 render prop pattern)的问题,就是如何组合 providers 和 consumers.当在一个 render 方法中把一堆 render prop 组件放在一起时,就会像这样 嵌套:
所以我们怎么避免这种情况你? 如果这样很麻烦,你可以用常规的方法来解决: utility 函数/组件. 这有个例子:
const ThemeContext = React.createContext('light')class ThemeProvider extends React.Component {/* code */} const ThemeConsumer = ThemeContext.Consumerconst LanguageContext = React.createContext('en')class LanguageProvider extends React.Component {/* code */} const LanguageConsumer = LanguageContext.Consumerfunction AppProviders({children}) { return ( `<LanguageProvider>` `<ThemeProvider>` {children} `</ThemeProvider>` `</LanguageProvider>` ) } function ThemeAndLanguageConsumer({children}) { return ( `<LanguageConsumer>` {language => ( `<ThemeConsumer>` {theme => children({language, theme})} `</ThemeConsumer>` )} `</LanguageConsumer>` ) }class App extends React.Component { render() { return ( `<AppProviders>` `<ThemeAndLanguageConsumer>` {({theme, language}) => `<div>`{theme} and {language}`</div>`} `</ThemeAndLanguageConsumer>` `</AppProviders>` ) } }
在这里的目的是为了使用常见的案例,结合特殊功能的函数/组件,使案例更加 工程化! 有道理么? 我希望它确实如此 我这有另外一个例子,在这真实的展示出嵌套有多糟糕以及怎样使用一个jmeas 的一个称为react-composer
utility 方法 来实现它链接
我应该提到的是,我不希望你需要在实践中嵌套 render props 组建。无论何时,你都可以创建一个简单的组建,将它们组合在一起并使用该组件。
总结
正如我之前所说的,我对于这个新的API 非常的振奋。这个API 目前没有发布,但是一个会包含在下一个发布的 React minor版本中。 不同担心,之前的 API 会继续正常工作,直到下一个 major 版本发布。所以,每个人都有时间迁移。还有不要忘了,React 团队在 Facebook 有超过 50,000 个 React components 需要维护,所以,将来很有可能会发布一个 codemod 去自动更新大多数人的代码(就像之前的版本一样)。
我对这个新API所能提供的东西感到兴奋。正如我最近在Twitter上提到的 (回应 Dan Abramov的 推文): 有太多的期待了!祝你好运!
不容错过的事:
react-broadcast
是 Michael Jackson 的一个库,提供与context同样的功能. 下一个版本 将是对于React.createContext
(对eJames Kyle的shoutout 以及创建create-react-context
).我实际上使用react-broadcast 在我的高级react课程中当新的contextAPI正式发布时我将不得不更新 .react-fns
: 浏览器API由Jared Palmer 转变为声明性React组件和HoC'sreact-composer
: 由 jmeas撰写渲染道具组件(我在上面的代码框中使用的)react-contextual
: Paul HenschelPaul Henschel的Reacts新context API的小助手
上周的一些推文:
附 如果你喜欢这些, 确保 邮箱订阅, _在twitter上关注我, _帮我买午餐, 在patreon支持我, 并且 和你的朋友分享这些
并且,转发这是与朋友分享这个不错的方法:
大家好!我叫Kent C. Dodds. 我是一名工作在PayPal 的全栈工程师. 我在PayPal 我职级是 the TC39. 我比较热衷于 开源社区. 我在 egghead.io, Frontend Masters, and Workshop.me上是一名讲师. 并且我还是一名 谷歌开发者. I’m 我幸福地结婚了,还有四个孩子的父亲。 我喜欢我的家人,喜欢编码,JavaScript和React.
译文出处:https://www.zcfy.cc/article/react-s-new-context-api
共同学习,写下你的评论
评论加载中...
作者其他优质文章