所以我正在学习一些教程,我对使用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} />
答案 0 :(得分:3)
首先,什么是HOC?
HOC是Higher-order component。这意味着它是一个函数,它将第一个参数作为一个组件,然后返回一个组件。
从这个定义中你可以立即看到:
Aux是一个功能组件。通过定义继承自React.Component的类来创建Classic React组件。更新,更简单的定义组件的方法是创建仅接受props
作为第一个参数的函数,并返回应该呈现的内容。
所以基于上面的代码,如果有人能够解释究竟发生了什么,事情的执行和渲染方式?
好吧,让我们看看App
作为一个组件。我们有withClass
和App
,您正在导出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"/>;
我希望有所帮助!