[译]迁移到新的 React Context Api
随着 React 16.3.0 的发布,context api 也有了很大的更新。我已经从旧版的 api 更新到了新版。这里就分享一下我(作者)的心得体会。 回顾下面是一个展示如何使用旧版 api 的例子: function Usage(props) { return ( <Toggle onToggle={props.onToggle}> <Toggle.On>The button is on</Toggle.On> <Toggle.Off>The button is off</Toggle.Off> <div> <Toggle.Button /> </div> </Toggle> ) } 上面的代码会返回一个复合组件 旧的 Context Api这是一个旧版 context api 的应用例子: const TOGGLE_CONTEXT = "__toggle__"; // Toggle on function ToggleOn({ children }, context) { const { on } = context[TOGGLE_CONTEXT]; return on ? children : null; } ToggleOn.contextTypes = { [TOGGLE_CONTEXT]: PropTypes.object.isRequired }; // Toggle off function ToggleOff({ children }, context) { const { on } = context[TOGGLE_CONTEXT]; return on ? null : children; } ToggleOff.contextTypes = { [TOGGLE_CONTEXT]: PropTypes.object.isRequired }; // Toggle button function ToggleButton(props, context) { const { on, toggle } = context[TOGGLE_CONTEXT]; return <Switch on={on} onClick={toggle} {...props} />; } ToggleButton.contextTypes = { [TOGGLE_CONTEXT]: PropTypes.object.isRequired }; // Toggle class Toggle extends React.Component { static On = ToggleOn; static Off = ToggleOff; static Button = ToggleButton; static defaultProps = { onToggle: () => {} }; static childContextTypes = { [TOGGLE_CONTEXT]: PropTypes.object.isRequired }; state = { on: false }; toggle = () => this.setState( ({ on }) => ({ on: !on }), () => this.props.onToggle(this.state.on) ); getChildContext() { return { [TOGGLE_CONTEXT]: { on: this.state.on, toggle: this.toggle, } }; } render(){ return <div>{this.props.children</div> } } 在就的 API 里,你必须用一个字符串指定要分享的 state。然后通过 另一个问题是如果 新的 Context API新的 context api 没有这些问题,这也是我为什么这么激动的原因。上面的例子可以更新为: const ToggleContext = React.createContext({ on:false, toggle: () => {}, }); class Toggle extends React.Component { static On = ({children}) => ( <ToggleContext.Consumer> {({on})=>(on ? children: null)} </ToggleContet.Consumer> ) static Off = ({children}) => ( <ToggleContext.Consumer> {({on}) => (on ? null : children)} </ToggleContext.Consumer> ); static Button = props => ( <ToggleContext.Consumer> {({on, toggle}) => ( <Switch on={on} toggle={toggle} {...props} /> )} </ToggleContext.Consumer> ) toggle = () => this.setState( ({on}) => ({on: !on}), () => this.props.onToggle(this.state.on) ); state = {on: false, toggle: this.toggle}; render() { return ( <ToggleContext.Provider value={}> {this.props.children} </ToggleContext.Provider> ); } } 旧的API的问题都没有了。现在不仅没有了不直接的字符串,还有了明显的组件: 另一个通过 最后一个非常好的改变是子组件都使用了render props模式。这样在新的context api里也可以对外界暴露非常优雅的接口。 新api的问题这就是在新的api里通过 这个影响在实际使用的时候会很大。一般来说最好是传入一个只有在state改变时才改变的值。也就是为什么说 只不过这也还是会有一个小问题,我需要把 总结新的context api绝对是React团队带来的一个非常好的改变。希望你也能和我一样的喜欢。 另外:如果你还不能用16.3.0这个版本,那么你可以添加一个polyfill来使用新的api。这个polyfill是create-react-context。 from:https://blog.kentcdodds.com/migrating-to-reacts-new-context-api-b15dc7a31ea0 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |