- 依赖注入
- 参考资料:
- 参考资料:
依赖注入
在React中,想做依赖注入(Dependency Injection)其实相当简单。请看下面这个例子:
// Title.jsxexport default function Title(props) {return <h1>{ props.title }</h1>;}
// Header.jsximport Title from './Title.jsx';export default function Header() {return (<header><Title /></header>);}
// App.jsximport Header from './Header.jsx';class App extends React.Component {constructor(props) {super(props);this.state = { title: 'React Dependency Injection' };}render() {return <Header />;}}
试想,我们想把”React Dependency Injection”这个字符串传到我们的Title组件里面去。比较直观的方法是把这个字符串作为props传入Header组件,然后Header组件将这个字符串作为props传入Title组件。
在只有三个组件相互嵌套的情况下,上面的这种解决方式似乎能满足我们的需要。但是设想一下,随着组件数量的增加以及组件嵌套层次的加深,许多的组件都需要接收该组件本身并不需要关心的props,然后且简单地传递给子组件。直观上来看,上面的这种方法在这种情况下,似乎就不太适用了。
不过不用担心,事实上我们还有很多方法能实现依赖的注入,其中之一就是高阶组件(high-order component)。
// inject.jsxvar title = 'React Dependency Injection';export default function inject(Component) {return class Injector extends React.Component {render() {return (<Component{...this.state}{...this.props}title={ title }/>)}};}
// Title.jsxexport default function Title(props) {return <h1>{ props.title }</h1>;}
// Header.jsximport inject from './inject.jsx';import Title from './Title.jsx';var EnhancedTitle = inject(Title);export default function Header() {return (<header><EnhancedTitle /></header>);}
在上面这种实现中,title这个字符串作为我们的数据没有被注入到整个的组件树中。相反,我们的数据只传递给了需要关注这个数据的组件。
这种实现看上去比上面优雅了很多,但事实上并没有完全解决我们的问题。
我们将title这个字符串通过inject这个高阶组件注入了进去,但是如果我的title字符串只能在我的Header组件这个层级获得呢?那么是不是意味着我还需要再从Header组件传递给inject组件呢?
这是一个实际可能会发生的问题,为了解决这个问题,接下来需要介绍一下React的Context API。
在React框架中,存在着context这样一个概念。context有点类似与事件总线(Event Bus),是一个无论在哪都可以访问的对象。不同的是,但是在context里面维持的全部都是我们的数据而非事件。context贯穿于整个组件树中,所有的组件都可以访问context。
使用方法
var context = { title: 'React in patterns' };class App extends React.Component {getChildContext() {return context;}// ...}App.childContextTypes = {title: PropTypes.string};
A place where we need data
class Inject extends React.Component {render() {var title = this.context.title;// ...}}Inject.contextTypes = {title: PropTypes.string};
需要注意的是,在最新的React官方文档中,Context已经不太被官方推荐使用了。Why Not To Use Context
参考资料:
- What is Dependency Injection?
- The Basics of Dependency Injection
- Dependency injection in JavaScript
- DI In React
