react-intl中injectIntl方法的源码简析
发布时间:2020-12-15 07:38:54 所属栏目:百科 来源:网络整理
导读:问题:react-intl用法部分 function Home(props) { return ( DocumentTitle title={`Ant Design - ${props.intl.formatMessage({ id: 'app.home.slogan' })}`} div className="main-wrapper" Link / Banner {...props} / Page1 {...props} / Page2 {...props
问题:react-intl用法部分 function Home(props) { return ( <DocumentTitle title={`Ant Design - ${props.intl.formatMessage({ id: 'app.home.slogan' })}`}> <div className="main-wrapper"> <Link /> <Banner {...props} /> <Page1 {...props} /> <Page2 {...props} /> <Page3 {...props} /> <Page4 {...props} /> <style dangerouslySetInnerHTML={{ __html: getStyle() }} /> </div> </DocumentTitle> ); } export default injectIntl(Home);//传入一个包裹组件WrappedComponent,返回一个InjectIntl组件实例 问题:源码分析部分 /* * Copyright 2015,Yahoo Inc. * Copyrights licensed under the New BSD License. * See the accompanying LICENSE file for terms. */ // Inspired by react-redux's `connect()` HOC factory function implementation: // https://github.com/rackt/react-redux import React,{Component} from 'react'; import invariant from 'invariant'; import {intlShape} from './types'; import {invariantIntlContext} from './utils'; function getDisplayName(Component) { return Component.displayName || Component.name || 'Component'; } export default function injectIntl(WrappedComponent,options = {}) { const { intlPropName = 'intl',withRef = false,//为WrappedComponent添加一个ref属性 } = options; class InjectIntl extends Component { static displayName = `InjectIntl(${getDisplayName(WrappedComponent)})`; static contextTypes = {//可以接受父组件存放在context中的intl属性 intl: intlShape,}; static WrappedComponent = WrappedComponent; constructor(props,context) { super(props,context); invariantIntlContext(context); } //getWrappedInstance调用时候欧返回我们的ref="wrappedInstance" getWrappedInstance() { invariant(withRef,'[React Intl] To access the wrapped instance,' + 'the `{withRef: true}` option must be set when calling: ' + '`injectIntl()`' ); return this.refs.wrappedInstance; } render() { return ( <WrappedComponent //我们的WrappedComponent会被存放一个intl属性作为props,这是为什么上面的例子可以通过props直接获取到 {...this.props} {...{[intlPropName]: this.context.intl}}//如果有ref属性,那么返回我们的WrappedComponent实例 ref={withRef ? 'wrappedInstance' : null} /> ); } } return InjectIntl; } 问题:为什么要用这个InjectIntl而不是直接放在Context中,就像下面的例子就是直接放在context中的 import React,{PropTypes} from 'react'; import {intlShape,FormattedRelative} from 'react-intl'; const Component = ({date},context) => ( //如果有ContextTypes,那么第二个参数就是我们的context <span title={context.intl.formatDate(date)}> //change here,use context directly <FormattedRelative value={date}/> </span> ); Component.propTypes = { date: PropTypes.any.isRequired,}; Component.contextTypes = { intl: intlShape.isRequired,} export default Component; 而下面的例子就是通过injectIntl来完成的 import React,{PropTypes} from 'react'; import {injectIntl,intlShape,FormattedRelative} from 'react-intl'; const Component = ({date,intl}) => ( <span title={intl.formatDate(date)}> <FormattedRelative value={date}/> </span> ); Component.propTypes = { date: PropTypes.any.isRequired,intl: intlShape.isRequired,}; export default injectIntl(Component); injectIntl提供了一个非直接层,他的作用是解耦,使用React的intl来替代我们的React的context。如果以后React的context的API发生变化,代码的改变只要在injectIntl中进行就可以了,而不是在整个应用中 问题:方才说了第二个参数是context,我们看看都有哪些方法会传入第二个参数context
|