用Hoc反应渲染

时间:2018-05-17 16:31:20

标签: javascript reactjs react-native

所以我正在学习一些教程,我对使用HOC时的渲染方式感到困惑

首先,我猜道具从父母传给孩子,是一个方向?

这里我们创建了两个HOC, Aux withclass

除了通过props.children

之外,Aux并没有做任何特别的事情
import { Component, ChangeDetectorRef } from '@angular/core'
.
.
.
constructor(private cdr: ChangeDetectorRef) {}
.
.
.
getCarName() {
  this.cdr.detectChanges();
  return this.carName;
}

withClass HOC函数有两个参数App和className ..

const aux = (props) => props.children;

export default aux;

我们作为参数传递的App.js看起来像这样

const withClass = (WrappedComponent, className) => {
   return class extends Component {
       render () {
           return (
               <div className={className}>
                   <WrappedComponent {...this.props} />
               </div>
           )
       }
   }

[问题] 所以基于上面的代码,如果有人可以解释究竟发生了什么,事情的执行和渲染方式?

其次,我们在withClass HOC 中使用了 import React, { PureComponent } from 'react'; import classes from './App.css'; import Persons from '../components/Persons/Persons'; import Cockpit from '../components/Cockpit/Cockpit'; import Aux from '../hoc/Aux'; import withClass from '../hoc/withClass'; class App extends PureComponent { //something render () { if ( this.state.showPersons ) { persons = <Persons persons={this.state.persons} clicked={this.deletePersonHandler} changed={this.nameChangedHandler} />; } return ( <Aux> <button onClick={() => { this.setState( { showPersons: true } ) }}>Show Persons</button> <Cockpit appTitle={this.props.title} showPersons={this.state.showPersons} persons={this.state.persons} clicked={this.togglePersonsHandler} /> {persons} </Aux> ); } } export default withClass( App, classes.App ); ,因为根据教师的说法,他们被包裹,因此我们的其他组件,即使他们得到道具,他们也无法通过。有人可以用一个例子来解释这个吗?另外{...this.props}会创建所有道具的副本吗?并且不应该像{...this.props}而不是<WrappedComponent = {...this.props} />

1 个答案:

答案 0 :(得分:3)

首先,什么是HOC?

HOC是Higher-order component。这意味着它是一个函数,它将第一个参数作为一个组件,然后返回一个组件。

从这个定义中你可以立即看到:

  • withClass是HOC
  • Aux 是HOC

Aux是一个功能组件。通过定义继承自React.Component的类来创建Classic React组件。更新,更简单的定义组件的方法是创建仅接受props作为第一个参数的函数,并返回应该呈现的内容。

  

所以基于上面的代码,如果有人能够解释究竟发生了什么,事情的执行和渲染方式?

好吧,让我们看看App作为一个组件。我们有withClassApp,您正在导出withClass(App, classes.App)。如果我们使用功能组件而不使用HOC,它会是什么样子?它看起来像这样:

const AppWithClass = props =>
  <div className={classes.App}>
    <App/>
  </div>

在这种情况下,没有道具传递给App 。因此,使用此用例,无需通过编写props来传递{...props}。然后,您只需导出AppWithClass。

但通常你会把HOC写成可重复使用的。在这种情况下,您不知道将传递给您的HOC的组件是否会收到道具。出于这个原因,您希望您创建的组件接受传递给它的任何props,并希望将它们通过传递给包装组件。

我们假设您有Button组件,其中包含参数colour。您通常会像这样使用它:

<Button colour="red"/>

但是你想用div包装它并向div添加一个类。所以你使用withClass如下:

const ButtonWithClass = withClass(Button, "button-class");

现在您可以使用Button,如下所示:

<ButtonWithClass colour="red"/>

你真正得到的是:

<div className="button-class">
  <Button colour="red"/>
</div>

如果在{...this.props} HOC中呈现WrappedComponent时未写withClass,则colour将不会传递到Button。在您的HOC中,WrappedComponent在上述情况下等于Button

语法{...this.props}Object literal spread syntax和JSX自身行为的组合。以这种方式使用的Object spread语法意味着给定对象的键将成为prop名称,值将成为它们各自的值。所以当你写{...{ colour: 'red' }}时,你要求JSX从你内联定义的对象中获取道具。

继续上面的例子:

<ButtonWithClass colour="red"/>

withClass内,这相当于:

const WrappedComponent = Button;
return <WrappedComponent {...this.props}/>;

此处this.props等于{ colour: 'red' }。所以上面变成了:

const WrappedComponent = Button;
return <WrappedComponent {...{ colour: 'red' }}/>;

然后变为:

const WrappedComponent = Button;
return <WrappedComponent colour="red"/>;

我希望有所帮助!