1.0.1 • Published 6 years ago

as-with-context v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

with-context

这个包是干嘛的

React v16.3.0 版本提供了官方正式版本的 context API,看到这个消息我是非常期待的,仿佛看到摆脱了Redux的自己在夕阳下奔跑的样子,但还没等我高兴几下,但是官网的demo就给我破了一盆凉水。

官方的demo是这么写的:

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 ThemedButton extends React.Component {
  render() {
    return (
      <ThemeContext.Consumer>
        {theme => <Button theme={theme} />}
      </ThemeContext.Consumer>
    );
  }
}

???好像有什么不对劲,这个 Consumer 好像只能应用在 render() 里面啊,没有放在 props 里的数据我怎么拿他来替代 Redux 😭。

经过了短暂的失落后,我突然想起了一个东西,没错,就是 react-router 里面的 withRouter:

export withRouter(Home)

这个API能够将路由的相关数据映射到组件 props 上,然后在组件内就能为所欲为了,那么,我自己写一个 withContext 把当前组件用到的 Context 数据扔到props上不久好了嘛,所以我写了这个包。

如何使用

首先是标准步骤,安装:

npm i as-with-context -S

然后,这样:

//context.js
const ThemeContext = React.createContext('light')

export const ThemeProviderr = ThemeContext.Provider
export const ThemeConsumer = ThemeContext.Consumer

// 组件内
import React, { Component } from 'react'
import { ThemeConsumer } from './context'
import withContext from 'as-with-context'

class Home extends Component {
  ...
}

export default withContext(Home, ThemeConsumer, 'myTheme')

这样,ThemeContext 中的相关数据就可以通过 this.props.myTheme 来访问啦

使用多个Context

当然,我们在一个组件内不可能只使用一个全局状态,所以使用 Context API 就(经常)会出现同时使用多个 Context 的情况。

先看以下官方的demo

function Content() {
  return (
    <ThemeContext.Consumer>
      {theme => (
        <UserContext.Consumer>
          {user => (
            <ProfilePage user={user} theme={theme} />
          )}
        </UserContext.Consumer>
      )}
    </ThemeContext.Consumer>
  );
}

enmmmm,看着就好麻烦的样子,这个不能忍啊。

所以针对这种情况,我们还有另外一个API来处理多个 context 的情况

import { ThemeConsumer, InfoConsumer } from './context'
import { withContexts } from 'as-with-context'

class Home extends Component {
  ...
}

const Contexts = [
  { name: 'myTheme', consumer: ThemeConsumer },
  { name: 'myInfo', consumer: InfoConsumer }
]

export default withContexts(Home, Contexts)

铛铛铛铛铛,这样是不是看着就清爽多啦。然后依然是从 props 中直接取数据就可以了

文档

withContext(component, consumer, name)

name 为空的话,会是用默认值 'consumer' 来标记

withContexts(component, ContextsList)

Contexts 中的元素,name 相同时,后一项会覆盖前一项,请不要作死

写在最后

这个项目是我从最近的项目中总结出来的办法,存在着许多不足,欢迎交流,我们issue见~

1.0.1

6 years ago

1.0.0

6 years ago