React高阶组件
简单地说,高阶组件(Higher-Order Components)就是一个函数,而参数是一个组件,返回值是一个相对增强性的组件。
一、用途
属性代理
反向继承(集成)
最终的目的:抽出公共的逻辑进行封装。
(一)属性代理
- 在根组件index.js传入username
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App username="lxc" />, document.getElementById('root'));
- 在App.js中使用使用了高阶组件,所以username的值传到了高阶组件中
import React, { Component } from "react";
export default (WrapperComponent) => {
return class extends React.Component {
constructor() {
super();
this.state = {
title: "首页",
age: 18,
sign: "lxc"
}
}
render() {
let { title, ...rest } = this.state;
console.log(this.props, "高阶组件");
return (
<div>
高阶组件header
<WrapperComponent {...this.props}{...rest}></WrapperComponent>
</div>
)
}
}
}
- App.js可以接收到根组件传到高阶组件的中props,以及高阶组件中的state
import React,{Component} from 'react';
import headerHoc from "./hoc/headerHoc";
class App extends Component{
render(){
console.log(this.props);//username: "lxc",age: 18,sign: "lxc"
return(
<div>app</div>
)
}
}
export default headerHoc(App);
(二) 反向继承
- 在App.js中使用高阶组件
import React, { Component } from 'react';
import footerHoc from "./hoc/footerHoc"
class App extends Component {
constructor() {
super();
this.state = {
componentName:"App组件"
}
}
render() {
return (
<div>app</div>
)
}
handleClick(){
console.log("123",this);//this通过bind改变为高阶组件
}
componentDidMount(){
console.log("componentDidMount")
}
}
export default footerHoc(App);
- 在高阶组件中,执行App组件中的方法,并更改生命周期
import React from "react"
export default (WrapperComponent) => {
return class extends WrapperComponent {
render() {
return (
<div>高阶组件
{super.render()}
<button onClick={super.handleClick.bind(this)}>点击</button>
</div>
)
}
componentDidMount(){
console.log(123);
super.componentDidMount();//打印componentDidMount
}
}
}
二、基本使用
(一)加载loading
- App.js
import React, { Component } from 'react';
import Loading from "./hoc/loading";
class App extends Component {
constructor() {
super();
this.state = {
success:false
}
}
render() {
return (
<div>app</div>
)
}
componentDidMount(){
setTimeout(()=>{
this.setState({
success:true
})
},2000)
}
}
export default Loading(App);
- 高阶组件loading
import React from "react"
export default (WrapperComponent) => {
return class extends WrapperComponent{
render(){
if(this.state.success){
return super.render();
}else{
return(
<div>loading...</div>
)
}
}
}
}
(二) 增加跨组件传值
- createContext.js
import React from "react"
export let { Provider, Consumer } = React.createContext();
- index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from "./createContext"
ReactDOM.render(
<Provider value={{
username: "lxc",
age: "18",
sex: "男"
}}>
<App />
</Provider>
, document.getElementById('root'));
- 使用高阶组件的one组件(one.jsx),只从父级取出需要的数据(eg:age)
import React, { Component } from 'react'
import connect from "../hoc/connect"
class one extends Component {
render() {
console.log(this);
return (
<div></div>
)
}
}
// 只从父级拿取自己想要的数据
const mapStateToProps=(state)=>({
age:state.age,
})
export default connect(one)(mapStateToProps)
- 高阶组件context.jsx,采用柯里化的方式(第一个参数是组件,第二个参数是回调)
import React, { Component} from 'react'
import { Consumer } from "../../createContext"
// 采用柯里化的方式,第一个参数是组件,第二个参数是回调
export default (Wrapper) => (mapStateToProps) => {
return class extends React.Component {
render() {
return (
<Consumer>
{
(value) => {
let props = mapStateToProps(value);
return <Wrapper {...props}></Wrapper>
}
}
</Consumer>
)
}
}
}
网友评论