高阶组件就是一个 React 组件包裹着另一个 React 组件编程
高阶组件的思路则是函数式的,每个扩展(Enhance)就是一个函数,接受要扩展的组件做为参数。若是要进行 3 个扩展,那么则能够级联,看起来就是:bootstrap
const newComponent = Enhance3(Enhance2(Enhance1(MyComponent)));
高阶组件的方式则使得每个 Enhance 以及被扩展的组件都只关心本身手里那点事。Enhance 不知作别人会怎么用它,被扩展的组件也不关心别人会怎么扩展它。负责人是那个将它们连在一块儿的”水管工”,即最后写串联代码的人。app
高阶组件的用法虽然用到了 ES6 的类继承,可是实际上却只是把它当个工具使用,而不是真的借助于 OO 的继承。在 React 中使用高阶组件部分替代 Mixins,仍然是很是函数化的思惟方式,即针对 ”转换” 编程。只不过是组件定义替代了函数而已。async
代码复用,逻辑抽象,抽离底层准备(bootstrap)代码函数
渲染劫持工具
State 抽象和更改fetch
Props 更改this
import { Component } from "React" ; export const Enhance = (ComposedComponent) => class extends Component { constructor() { this.state = { data: null }; } componentDidMount() { this.setState({ data: 'Hello' }); } render() { return <ComposedComponent {...this.props} data={this.state.data} />; } }; import { Component } from "React"; import { Enhance } from "./Enhance"; class MyComponent = class extends Component { render() { if (!this.props.data) return <div>Waiting...</div>; return <div>{this.data}</div>; } } export default Enhance(MyComponent); // Enhanced component`
Props Proxy 能够作什么:code
更改 propscomponent
经过 refs 获取组件实例
抽象 state
把 WrappedComponent 与其它 elements 包装在一块儿
function ppHOC(WrappedComponent) { return class PP extends React.Component { render() { const newProps = { user: currentLoggedInUser } return <WrappedComponent {...this.props} {...newProps}/> } } }
function refsHOC(WrappedComponent) { return class RefsHOC extends React.Component { proc(wrappedComponentInstance) { wrappedComponentInstance.method() } render() { const props = Object.assign({}, this.props, {ref: this.proc.bind(this)}) return <WrappedComponent {...props}/> } } }
function ppHOC(WrappedComponent) { return class PP extends React.Component { constructor(props) { super(props) this.state = { name: '' } this.onNameChange = this.onNameChange.bind(this) } onNameChange(event) { this.setState({ name: event.target.value }) } render() { const newProps = { name: { value: this.state.name, onChange: this.onNameChange } } return <WrappedComponent {...this.props} {...newProps}/> } } }
function ppHOC(WrappedComponent) { return class PP extends React.Component { render() { return ( <div style={{display: 'block'}}> <WrappedComponent {...this.props}/> </div> ) } } }
能够用反向继承高阶组件作什么?
渲染劫持(Render Highjacking)
操做 state
它被叫作渲染劫持是由于高阶组件控制了 WrappedComponent 生成的渲染结果,而且能够作各类操做。
经过渲染劫持你能够:
读取、添加、修改、删除』任何一个将被渲染的 React Element 的 props
在渲染方法中读取或更改 React Elements tree,也就是 WrappedComponent 的 children
根据条件不一样,选择性的渲染子树
给子树里的元素变动样式
function iiHOC(WrappedComponent) { return class Enhancer extends WrappedComponent { render() { return super.render() } } } function iiHOC(WrappedComponent) { return class Enhancer extends WrappedComponent { render() { if (this.props.loggedIn) { return super.render() } else { return null } } } }
高阶组件能够 『读取、修改、删除』WrappedComponent 实例的 state,若是须要也能够添加新的 state。须要记住的是,你在弄乱 WrappedComponent 的 state,可能会致使破坏一些东西。一般不建议使用高阶组件来读取或添加 state,添加 state 须要使用命名空间来防止与 WrappedComponent 的 state 冲突。
export function IIHOCDEBUGGER(WrappedComponent) { return class II extends WrappedComponent { render() { return ( <div> <h2>HOC Debugger Component</h2> <p>Props</p> <pre>{JSON.stringify(this.props, null, 2)}</pre> <p>State</p><pre>{JSON.stringify(this.state, null, 2)}</pre> {super.render()} </div> ) } } }
function hoc(ComponentClass) { return class HOC extends ComponentClass { render() { if (this.state.success) { return super.render() } return <div>Loading...</div> } } } @hoc export default class ComponentClass extends React.Component { state = { success: false, data: null }; async componentDidMount() { const result = await fetch(...请求); this.setState({ success: true, data: result.data }); } render() { return <div>主要内容</div> } }
从上面的例子能够得出Higher-Order Components = Decorators + Components