为了账号安全,请及时绑定邮箱和手机立即绑定

React:Hooks 会取代 HOC 和渲染道具吗?

React:Hooks 会取代 HOC 和渲染道具吗?

手掌心 2021-06-08 13:14:38
从React Hooks FAQ 中,我们了解到钩子可以替代返回/渲染单个组件的 HOC 和渲染道具。我试图更好地理解这一点,以及为什么这是事实。我们先来看看 HOC:HOC 是一个函数,它将一个组件作为参数,将它包装在周围的逻辑中,如效果和状态,并返回一个新组件。自定义钩子究竟如何取代它?我们仍然需要用其他逻辑包装输入函数的函数。查看渲染道具:渲染道具是我们作为道具传递给另一个组件的组件,然后使用一些新的道具渲染传递的组件。我想我们可以通过创建一个返回完整组件的自定义钩子来替换它,然后在任何需要的组件中使用该钩子。因此,父级不必将组件作为道具传递给它的子级。这就是钩子会取代渲染道具的方式吗?对钩子如何在最常见的用例中替换 HOC 和渲染道具的解释,最好是代码示例,将不胜感激。
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

HOC 和渲染道具有很多不同的用途,所以我不可能将它们全部都涵盖在内,但基本上该段落指出,您使用 HOC/渲染道具的许多情况也可以通过钩子实现。这不会使 HOCs/render props 过时,但钩子是另一个可供您在组件之间共享代码的工具。


HOC/render prop 的一项常见工作是管理一些数据的生命周期,并将该数据传递给派生组件或子组件。在以下示例中,目标是获取窗口宽度,包括与之相关的状态管理和事件侦听。


HOC 版本:


function withWindowWidth(BaseComponent) {

  class DerivedClass extends React.Component {

    state = {

      windowWidth: window.innerWidth,

    }


    onResize = () => {

      this.setState({

        windowWidth: window.innerWidth,

      })

    }


    componentDidMount() {

      window.addEventListener('resize', this.onResize)

    }


    componentWillUnmount() {

      window.removeEventListener('resize', this.onResize);

    }


    render() {

      return <BaseComponent {...this.props} {...this.state}/>

    }

  }

  // Extra bits like hoisting statics omitted for brevity

  return DerivedClass;

}


// To be used like this in some other file:


const MyComponent = (props) => {

  return <div>Window width is: {props.windowWidth}</div>

};


export default withWindowWidth(MyComponent);


渲染道具版本:


class WindowWidth extends React.Component {

  propTypes = {

    children: PropTypes.func.isRequired

  }


  state = {

    windowWidth: window.innerWidth,

  }


  onResize = () => {

    this.setState({

      windowWidth: window.innerWidth,

    })

  }


  componentDidMount() {

    window.addEventListener('resize', this.onResize)

  }


  componentWillUnmount() {

    window.removeEventListener('resize', this.onResize);

  }


  render() {

    return this.props.children(this.state.windowWidth);

  }

}


// To be used like this:


const MyComponent = () => {

  return (

    <WindowWidth>

      {width => <div>Window width is: {width}</div>}

    </WindowWidth>

  )

}

最后但并非最不重要的是,钩子版本


const useWindowWidth = () => {

  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {

    const onResize = () => setWidth(window.innerWidth);

    window.addEventListener('resize', onResize);

    return () => window.removeEventListener('resize', onResize);

  }, [])

  return width;

}


// To be used like this:


const MyComponent = () => {

  const width = useWindowWidth();

  return <div>Window width is: {width}</div>;

}


查看完整回答
反对 回复 2021-06-18
  • 1 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信