在React

时间:2017-11-28 09:22:21

标签: javascript reactjs components higher-order-components

我一直在研究高阶组件的反应。我的要求是我有一个集合组件,我需要扩展它们,以便在不重写整个组件的情况下为它们提供更多功能。在这种情况下,我发现了HOC中的概念,其中可以使用纯函数扩展组件。我的问题是,我可以将扩展组件导出为普通组件。例如

需要扩展的组件

class foo extends React.Component {
    render(){
        //something
    }
}

export default foo;

HOC组件

function bar(foo) {
    render() {
         return <foo {...this.props} {...this.state} />;
    }
}

export default bar;

我能以这种方式使用组件吗?或者我做错了吗?

3 个答案:

答案 0 :(得分:5)

HOC将采用一个组件,添加更多功能并返回一个新组件,而不仅仅是返回组件实例,

你要做的是

function bar(Foo) {

   return class NewComponent extend React.Component {
        //some added functionalities here
        render() {
            return <Foo {...this.props} {...otherAttributes} />
        }
   }

}

export default bar;

现在,当您想要为组件添加某些功能时,您将创建组件的实例,如

const NewFoo = bar(Foo);

您现在可以使用

return (
    <NewFoo {...somePropsHere} />
)

此外,您可以允许HOC采用默认组件并将其作为默认组件导出并在其他地方使用,如

function bar(Foo = MyComponent) {

然后创建一个类似

的导出
const wrapMyComponent = Foo();
export { wrapMyComponent as MyComponent };

HOC的典型用例可以是HandleClickOutside功能,您可以根据handleClickOutside功能传递需要执行操作的组件

答案 1 :(得分:0)

另一种方式可能是这样的:

制作Foo组件

class Foo extends React.Component {
    render() {
      return ( < h1 > hello I am in Foo < /h1>)
      }
    }

制作HOC组件。

class Main extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const {
      component, props
    } = this.props;
    //extract the dynamic component passed via props.
    var Component = component;

    return ( < div > 
          < h1 > I am in main < /h1> 
          < Component {...props} > < /Component>
          </div > );
  }
}


ReactDOM.render( < Main component = {
    Foo
  } > < /Main>,
  document.getElementById('example')
);

工作代码here

答案 2 :(得分:0)

是的,你可以

const bar = (Foo) => {
   return class MyComponent extend Component {
        render() {
            return <Foo {...this.props} />
        }
   }
}

//我们的Foo组件代码

export default bar(Foo)

但同样取决于功能。例如:假设您正在使用反应路由器,并且想要在呈现组件之前检查用户是否存在,而不是通过HOC。例如:

<Route path="/baz" component={auth(Foo)} />

而是使用新组件。

注意:NewComponent连接到redux,user(state)作为props

传递
class NewRoute extends Component{
    render(){
        const {component:Component, ...otherProps} = this.props;

        return(
          <Route render={props => (
            this.props.user? (
              <Component {...otherProps} /> 
              ):(
              <Redirect  to="/" />
                )
            )} 
          />
        );
    }
}

然后在路线上

<NewRoute path='/foo' component={Foo} />