Javascript 为什么高阶组件比常规组件更有用?

Javascript 为什么高阶组件比常规组件更有用?,javascript,reactjs,Javascript,Reactjs,我似乎无法理解为什么高阶组件比常规组件更有价值?我读了一篇关于它们的教程,认为高阶组件很好,因为它们:1)允许代码重用、逻辑和引导抽象。2) 能够做渲染高举。3) 能够抽象状态并操纵它们。4) 能够操纵道具。资料来源: 代码中的高阶组件示例如下所示: function refsHOC(WrappedComponent) { return class RefsHOC extends React.Component { proc(wrappedComponentInstance) {

我似乎无法理解为什么高阶组件比常规组件更有价值?我读了一篇关于它们的教程,认为高阶组件很好,因为它们:1)允许代码重用、逻辑和引导抽象。2) 能够做渲染高举。3) 能够抽象状态并操纵它们。4) 能够操纵道具。资料来源:

代码中的高阶组件示例如下所示:

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}/>
    }
  }
}
函数refsHOC(WrappedComponent){
返回类RefsHOC扩展了React.Component{
过程(wrappedComponentInstance){
wrappedComponentInstance.method()方法
}
render(){
const props=Object.assign({},this.props,{ref:this.proc.bind(this)})
返回
}
}
}
这些代码看起来与接收道具的常规类定义几乎完全相同,并且您仍然能够在该类中“操纵道具”和“操纵状态”

class Something extends React.Component {
  constructor(props) {
    super(props);
    this.state = { food: 'no_food_received_yet' } 
  }
  componentDidMount() {
    this.setState({ food: 'apple' });
  }
  render() {
    return (
      <div>
       <p>{ this.state.food }</p>
       <h2>{ this.props.food }</h2>
      </div>
    );
  }
}
class.com组件{
建造师(道具){
超级(道具);
this.state={food:'还没有收到食物'}
}
componentDidMount(){
this.setState({food:'apple'});
}
render(){
返回(
{this.state.food}

{this.props.food} ); } }
事实上,我并没有操纵或改变道具,但我可以接收它们,将它们应用到状态并输出该状态


这并不是要抨击高阶组件——实际上恰恰相反。我需要理解我错在哪里,以及为什么我应该将高阶组件集成到我的react应用程序中。

想象一下,您有一个应用程序,其中某些屏幕是私有的,并且仅对经过身份验证的用户可用。想象一下你有3个这样的屏幕。现在,在每个屏幕的容器组件上,您可以使用逻辑来检查用户是否经过身份验证,如果经过身份验证,则让他们通过身份验证,或者在未通过身份验证时将他们发送回登录。这意味着完全相同的逻辑会发生3次。使用HOC,您可以只编写一次该逻辑,然后用HOC将每个私有屏幕包装起来,从而反复提供相同的逻辑,但代码只需要存在于一个地方。这是HOCs提供的代码重用的一个很好的例子。

HOCs绝对有用,但它们的用处与任何“高阶”函数的用处相同

考虑以下组成部分:

let Button = props => <button style={{ color: props.color }} />
let blueify = Component => props => <Component {...props} style={{ color: 'blue' }} />
let Button=props=>
您可以制作另一个名为BlueButton的组件:

let BlueButton = props => <Button color="blue" />
let BlueButton=props=>
这没什么问题,但也许你希望任何组件都是蓝色的,而不仅仅是一个按钮。相反,我们可以创建一个通用的HOC来“蓝化”传递的组件:

let Button = props => <button style={{ color: props.color }} />
let blueify = Component => props => <Component {...props} style={{ color: 'blue' }} />
let blueify=Component=>props=>
然后你可以做蓝色的按钮,蓝色的div,蓝色的任何东西

let BlueButton = blueify(Button)
let BlueDiv = blueify(props => <div {...props} />)
让BlueButton=blueify(按钮)
让BlueDiv=blueify(props=>)

高阶分量更一般化,因此理论上可以应用于更广泛的情况。在更一般的意义上,高阶组件(和更高级的语言)往往更具表现力

在你的例子中,差别显而易见。非通用(低阶)组件中有硬编码的HTML。这是编程101;像PI这样的常量声明比像3.14159这样的硬编码声明更受欢迎,因为它们赋予幻数以意义,并允许一点修改

高阶“组件”(在本例中为高阶函数)的一个简单示例是一个排序函数,它将排序函数作为其参数之一。通过允许外部函数控制排序,您可以修改排序行为,而无需修改排序函数本身