React Advanced components
Learn how to React advanced Components of MOOC
What is the React high-order component
A higher-order component takes a component as an argument and returns a new component. A higher-order component is really a function, not just a component.
Second, start Demo to get to know the advanced components
1. Demand analysis
To have a need for:
We split the components in the figure above, which can be divided into external modal prompt box components and internal information components.
The external modal component is constant, but the internal content, we might show different effects in different places. The diagram below.
So we need to wrap an external Modal prompt component, to wrap different internal components.
2. Project construction
// Create an empty project create-react-app XXXCopy the code
Let’s create some new files.
// A/index.js
import React from 'react';
import './index.css';
// Define a function
// Pass in a component as an argument
function A(WrappedComponent) {
// Return a component
return class A extends React.Component {
constructor (props) {
super(props);
this.state = {};
}
render () {
return (
<div className="a-container">
<div className="header">
<div className="title">prompt</div>
<div className="close">X</div>
</div>
<div>
<! -- Use it here -->
<WrappedComponent />
</div>
</div>)}}}// Throw the function
export default A
Copy the code
The A component is our external Modal prompt component. To wrap our internal components.
Let’s implement component B.
// B/index.js
import React from 'react';
import A from '.. /A/index.js';
import './index.css';
class B extends React.Component {
render() {
return (
<div className="wrap">
<img src="https://raw.githubusercontent.com/freya0608/High-order-component/master/src/imgs/B.png" alt="" />
</div>); }}<! Call A() to wrap our B component. -->
export default A(B);
Copy the code
The final result is:
At this point, an entry-level high-level component instance is ok.
Summary: Ways to use higher-order components:
The first is our above method, the second is to use decorators to achieve, the specific configuration you can check online.
Now we have the requirement that the contents of component B may determine the title of component A, so we need to pass the value to A through component B.
// A/index.js
import React from 'react';
import './index.css';
// Here we return an anonymous function that accepts the passed value
export default (title = 'I am the title') = > {// Then returns a function that accepts child components
return (WrappedComponent) = > {
// Return our external component
return class A extends React.Component {
constructor (props) {
super(props);
this.state = {};
}
render () {
return (
<div className="a-container">
<div className="header">
<! -- Here we use the value we passed -->
<div className="title">{title}</div>
<div className="close">X</div>
</div>
<div>
<WrappedComponent />
</div>
</div>)}}}}Copy the code
// B/index.js
import React from 'react';
import A from '.. /A/index.js';
import './index.css';
class B extends React.Component {
render() {
return (
<div className="wrap">
<img src="https://raw.githubusercontent.com/freya0608/High-order-component/master/src/imgs/B.png" alt="" />
</div>); }}<! -- Most of all here -->Export default A(' prompt I ')(B);Copy the code
In this way, we implement B to A component of the value, so that A component can dynamically change some places.
Third, proxy mode of higher-order components
To understand the high-level components of proxy mode, we need to know from prop, access ref, extraction state, package components four parts.
- props
// A/index
import React from 'react';
import './index.css';
export default (title = 'I am the title') = > {return (WrappedComponent) = > {
return class A extends React.Component {
constructor (props) {
super(props);
this.state = {};
}
render () {
// [1] First we can get the props passed to the outermost component
const prop = this.props;
console.log(prop);
return (
<div className="a-container">
<div className="header">
<div className="title">{title}</div>
<div className="close">X</div>
</div>
<div>
<! --[2] can be passed to B component -->
<! --[3] Sex is new -->
<WrappedComponent sex={'male'} {. this.props} / >
</div>
</div>)}}}}Copy the code
// B/index.js
import React from 'react';
import A from '.. /A/index.js';
import './index.css';
class B extends React.Component {
render() {
return (
<div className="wrap">
<! --[1] Props = props ()My name: {this.props. Name} My gender: {this.props. Sex}<img src="https://raw.githubusercontent.com/freya0608/High-order-component/master/src/imgs/B.png" alt="" />
</div>); }} export default A(' prompt I ')(B);Copy the code
In the APP we can set props, pass it to component A, which filters or adds props, and then pass it to COMPONENT B, so that B can receive the outermost layer and the props passed from component A. Also, as A is the middle layer, A has the authority to control which props B can get and can add some additional attributes.
<B name={'zjj'}></B>
Copy the code
- refs
// A/index
import React from 'react';
import './index.css';
export default (title = 'I am the title') = > {return (WrappedComponent) = > {
return class A extends React.Component {
constructor (props) {
super(props);
this.state = {};
}
[1] Defines a click event
handleClick = (a)= > {
this.wref.getName();
}
render () {
const prop = this.props;
console.log(prop);
return (
<div className="a-container">
<div className="header">
<div className="title">{title}</div>
<div className="close">X</div>
</div>
<div>
<! -- [2] bind ref -->
<WrappedComponent ref={ (v) = >This. wref = v} sex={' male '} {... this.props} /></div>
<div>
<! -- [3] Click the event trigger -->
<button onClick={this.handleClick}>Get the name</button>
</div>
</div>)}}}}Copy the code
Let’s define a getName method in B. So by clicking on the button in A, you can call
B/index
getName = (a)= > {
console.log('获取到了name')}Copy the code
- Extraction of state
// A.js
import React from 'react';
import './index.css';
export default (title = 'I am the title') = > {return (WrappedComponent) = > {
return class A extends React.Component {
constructor (props) {
super(props);
this.state = {
value: ' '
};
}
/ / click
handleClick = (a)= > {
this.wref.getName();
}
// [1] Sets val based on the input
handleOnInputChange = (e) = > {
this.setState({
value: e.target.value
})
}
render () {
const prop = this.props;
console.log(prop);
// [2] Set new props
var newProps = {
value: this.state.value, / / the incoming values
onInput: this.handleOnInputChange // Listen for input to the form
}
return (
<div className="a-container">
<div className="header">
<div className="title">{title}</div>
<div className="close">X</div>
</div>
<div>
<WrappedComponent ref={ (v) = >This. wref = v} sex={' male '} {... this.props} {... NewProps} /> // [3] Pass in child components</div>
<div>
<button onClick={this.handleClick}>Get the name</button>
</div>
</div>)}}}}Copy the code
// B/index.js // use the values passed in, so that the implementation of the child component can be extracted and put into a common component, unified management <inputtype="text" value={this.props.value} onInput={this.props.onInput} />
Copy the code
- Packaging components
In fact, we have implemented the effect of wrapping the internal components above.