函数作为 JS 的一等公民, 组件是 React 的一等公民,组件可以作为一个 props 向下传递,所以 React 具备了高度抽象化的能力
- 高阶组件特点利用 JSX 描述的子元素,可以注入父级组件的
this.props.children
,可以入侵增强组件能力,如权限,跳转,埋点,异常,描述,注入等
-
高阶组件如果内有将被包裹组件暴露出来,后续叠加的高阶组件都无法获取和注入到原始组件(wrappedComponent)
-
解决思路
render props
render callback
function as child
import React, {Component} from 'react'; import PropTypes from 'prop-types'; class Caffeinate extends Component { propTypes = {children: PropTypes.func.isRequired}; state = {coffee: "Americano"}; render() { return this.props.children(this.state.coffee) } }
-
直接将函数作为子函数,可认为是一个匿名组件
render( <Caffeinate> {(beverage) => <div>Drinking an {beverage}</div>} </Caffeinate>, document.querySelector("#root") );
-
通过 render()将 props 进行回传:
import React, {Component} from 'react'; import PropTypes from 'prop-types'; class Caffeinate extends Component { propTypes = {children: Proptypes.func.isRequired}; state = {coffee: "Americano"}; render() { return this.props.child(this.state.coffee) } } // usage render( <Caffeinate child={ {beverage} => <div>Drinking an {beverage}</div> }/>, document.querySelector("#root") )
-
render prop
利用props.children
将参数写在 JSX 子元素中,嵌套写法可以看清楚数据流动,解决了高阶组件反复嵌套的各类问题 -
对比高阶组件
- HOC 相比,render props 开放性提升, 功能抽象可以通过 render props 获取,render 可以访问父级的一切
- HOC mode: Parent Component -> HOC -> Children Component
- render props mode: Parent Component -> render props -> children Component || Parent Component -> Child Component
- Render props 存在问题
- this.props.children 不该作为函数调用,可以作为属性返回
- 渲染颗粒度变大,表格需要性能优化场景不合适
- renderProps 不是 React 组件,无法单独使用 redux 等数据管理工具
-
围绕那么多对于最普通的 props 传参而言可能是一个比较好的方式,renderProps 的控制放权思想也是为了解决组件 dom 结构定制化的问题
render() { return this.props.children } render() { return ( <div> <Header /> <Sidebar> <Toolar> <ul> <li></li> <li></li> </ul> </Toolar> </Sidebar> </div> ) }
- 某些场景下高阶组件也是不错的选择,也不会拒绝使用使用
- 在不为组件做注入的情况,HOC 的生命周期实现权限,埋点,在层级少是使用依赖注入很方便
- 在最佳实践的衡量下,不用把最完美的实践全部在代码中重构,没必要局限一种风格或者崇尚多种风格写代码