React---扩展补充

发布于:2025-06-06 ⋅ 阅读:(22) ⋅ 点赞:(0)

一些额外的扩展

4.3 高阶组件

高阶组件是参数为组件,返回值为新组件的函数;

  • 高阶组件 本身不是一个组件,而是一个函数;
  • 其次,这个函数的参数是一个组件,返回值也是一个组件;
import React from "react";

function App() {
  // 高阶组件
  function higherOrderComponents(WrapperComponent) {
    class NewComponent extends React.Component {
      render() {
        return <WrapperComponent />;
      }
    }
        // 函数组件
    function NewComponent(props){
      return <WrapperComponent {...props}/>
    }
    NewComponent.displayName = "jyx";//重新命名组件名称,所有组件都有,没有什么意义
    return NewComponent;
  }

  class WrapperComponent extends React.Component {
    render() {
      return (
        <div>
          APP
        </div>
      );
    }
  }

  const Cpn = higherOrderComponents(WrapperComponent);
  return (
    <div className="App">
      <Cpn />
    </div>
  );
}

export default App;

4.4 高阶组件的应用

1、props增强

当我们有多个组件的时候,我们想要统一添加一个属性,一个个添加十分麻烦,我们就可以使用高阶组件的props增强

首先我们要创建一个高阶组件:传入的是组件和添加的属性

function enhanceProps(WrapperComponent , otherProps){
    return props => <WrapperComponent  {...props}  {...otherProps}/> 
}

然后我们可以写组件来共享高阶组件

const HomeProps = enhanceProps(Home , { region: "中国" })
const AboutProps = enhanceProps(About , { region: "重庆" })

最后使用就可以了

注意:果你想在组件中显示 region,需要在 Home 和 About 组件里加上:

render() {
    return (
      <div>
        <HomeProps nickname="jyx" level={90} ></HomeProps>
        <AboutProps nickname="hcy" level={80}></AboutProps>
        
      </div>
    )
  }
}
class Home extends PureComponent{
    render(){
        // 要使用region
            const {nickname , level , region} = this.props;
        return(
            <div>{`姓名:${nickname} , 级别:${level} , 地区:${region}`}</div>
        )
    }
    
}
class About extends PureComponent{
    render(){
            const {nickname , level , region} = this.props;
        return(
            <div>{`姓名:${nickname} , 级别:${level} , 地区:${region}`}</div>
        )
    }
    
}

props曾庆数据来自context

定义context:

import React, { createContext, PureComponent } from 'react'

export default class App extends PureComponent {
  render() {
    return (
      <div>
        {/* 4.使用组件,不必传入参数 */}
        <HomeProps ></HomeProps>
        <AboutProps ></AboutProps>
        
      </div>
    )
  }
}
class Home extends PureComponent{
    render(){
            const {nickname , level , region} = this.props;
        return(
            <div>{`姓名:${nickname} , 级别:${level} , 地区:${region}`}</div>
        )
    }
    
}
class About extends PureComponent{
    render(){
            const {nickname , level , region} = this.props;
        return(
            <div>{`姓名:${nickname} , 级别:${level} , 地区:${region}`}</div>
        )
    }
    
}
// 1.创建context对象
const UserContext = createContext({
    userbname:"jyx",
    level:90,
    region:"中国"
})
// 2.定义一个高阶组件
function withUser(WrapperComponent){
    return props => {
        return (
            <UserContext.Consumer>
               {
                // 在组件里面使用user
                user => <WrapperComponent  {...props} {...user}/>
               }
            </UserContext.Consumer>
        )
    }
    
}
// 3.定义组件
const HomeProps = withUser(Home)
const AboutProps = withUser(About)


2、渲染判断鉴权
  • 在开发中,我们可能遇到这样的场景:
    • 某些页面是必须用户登录成功才能进行进入;
    • 如果用户没有登录成功,那么直接跳转到登录页面;
  • 这个时候,我们就可以使用高阶组件来完成鉴权操作
import React, { PureComponent } from 'react'

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <AuthPage isLogin={true}></AuthPage>
      </div>
    )
  }
}
// 1.定义一个高阶组件
function withLogin (WrappedComponent){
//    返回的是组件
return class extends PureComponent{
    render(){
         const {isLogin , props} = this.props;
    if(isLogin){
        // 如果成功登录
        return <WrappedComponent {...props} />
    }else {
        // 否则
        return <Login />
    }
    }
}
}
// 2.login
class Login extends PureComponent {
    render(){
        return (
            <div>
                请先登录
            </div>
        )
    }
  }
//   3.定义一个组件来使用高阶组件
class CartPage extends PureComponent{
    render(){
        return (
            <h2>我是购物车组件</h2>
        )
    }
}
const AuthPage = withLogin(CartPage);
3、劫持生命周期
import React, { PureComponent } from 'react'

export default class App extends PureComponent {
  render() {
    return (
      <div>
        <HomeAuto />
      </div>
    )
  }
}
// 1.定义高阶组件
function WithRenderTime(WrappedComponent){
    return class extends PureComponent {
        // 获取开始渲染的时间
        componentWillMount(){
            this.beginTime = Date.now();
        }
        // 获取渲染结束时间
        componentDidMount(){
            this.endTime = Date.now();
            // 获取时长
            const during = this.endTime = this.beginTime;
            console.log(`${WrappedComponent.name} 渲染时间为: ${during}}`)
        }
        // 渲染\
        render(){
            return <WrappedComponent {...this.props}/>
        }
    }
}
// 2.使用
class Home extends PureComponent{
    render(){
        return (
            <div>home</div>
        )
    }
}
const HomeAuto = WithRenderTime(Home);


10.5 转发ref

  • ref不能应用于函数式组件:因为函数式组件没有实例,所以不能获取到对应的组件对象
  • 在开发中我们可能想要获取函数式组件中某个元素的DOM,这个时候我们应该如何操作呢?通过forwardRef高阶函数;
import React, { createRef, forwardRef, PureComponent } from 'react'

export default class App extends PureComponent {
    constructor(){
        super();
        // 3.创建一个ref
        this.profieRef = createRef();
    }
    handelClick = () => {
        console.log(this.profieRef.current)
    }
  render() {
    return (
      <div>
        {/* ref的转发:
        在开发中我们可能想要获取函数式组件中某个元素的DOM,这个时候我们应该如何操作呢?
        通过forwardRef高阶函数; */}
        {/* 2.使用 */}
        <Profile ref={this.profieRef}></Profile>
        <button onClick={this.handelClick}>点击获取ref</button>

      </div>
    )
  }
}
// 1.创建一个forwardRef
const Profile =forwardRef(
     function (props , ref){

    return <p ref={ref}>Profile</p>

})

10.6 Portal

某些情况下,我们希望渲染的内容独立于父组件,甚至是独立于当前挂载到的DOM元素中(默认都是挂载到id为root的DOM元素上的)。
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案:

  • 第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment;
  • 第二个参数(container)是一个 DOM 元素;