React - 高级用法

news2024/11/29 1:56:02

React高级用法

Hooks

Reducer

在这里插入图片描述

useReducer:

import React, { useReducer, useState } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 }
        case 'decrement':
            return { count: state.count - 1 }
        default:
            console.log('格式不通过!');
    }
}

export default function Reducer() {
    const [number, setNumber] = useState(0);
    
    const [state, dispatch] = useReducer(reducer, initalState);
    
    return (
        <div>
            {state.count}
            <button onClick={() => dispatch({ type: 'increment' })}>+</button>
        </div>
    )
}

Ref

用来指代具体的dom节点

类组件: createRef

import React, { Component } from 'react';

export default class ClassRef extends Component {
    
    constructor(props) {
        super(props);
        
        this.eleRef = createRef();
        this.inputRef = createRef();
    }
    
    handleClick = () => {
        this.inputRef.current.focus();
        console.log(this.eleRef.current);
    }
    
    render() {
        return (
            <div>
                <div id="xxx" ref={this.eleRef}> eleRef </div>
                <input ref={this.inputRef} />
                
                <button onClick={this.handleClick}></button>
            </div>
        )
    }
    
}

函数组件:useRef

import { useRef } from 'react'

export default function FuncRef(props) {
    
    const eleRef = useRef(null);
    const inputRef = useRef(null);
    
    return (
        <div>
            <div id="xxx" ref={this.eleRef}> eleRef </div>
            <input ref={this.inputRef} />
            
            <button onClick={this.handleClick}></button>
        </div>
    )
    
}

Ref转发

类似于vue中 调用子组件的方法 refs.xxx()
在这里插入图片描述

Context上下文

Provider
Comsumer
对应Vue,就是provide,inject
形成一个生成与消费模式的上下文

类组件用法

import { createContext } from 'react';

const ThemeContext = createContext('light');

//    ClassContext.jsx
export default class ClassContext extends Component {
    
    constructor(props) {
        super(props);
        this.state = {
             theme: 'light'
        }
    }

    render() {
        return (
            <div>
                <ThemeContext.Provider
                    value={this.state.theme}
                >
                    <Parent />
                    <button onClick={() => this.setState({ theme: 'light' })}></button>
                </ThemeContext.Provider>
            </div>
        )
    }
}

const Parent = () => {
    return (
        <div>
            <Child1 />
            <Child2 />
        </div>
    )
}

class Child1 extends Component {

    static contextType = ThemeContext;
    render() {
        return (
            <div>
                {this.context}
            </div>
        )
    }
}

class Child2 extends Component {
    render() {
        return (
            <ThemeContext.Consumer>
                {
                    (theme) => (
                        <div>{theme}</div>
                    )
                }
            </ThemeContext.Consumer>
        )
    }
}

History包装(函数组件)

import { useContext, useState, createContext } from 'react';

const ThemeContext = createContext();
const history = window.history;

export default function FuncContext() {
    return (
        <ThemeContext.Provider value={history}>
            <Parent />
        </ThemeContext.Provider>
    )
}

const Parent = () => {
    return <Child />;
}

const withRouter = (Component) => {
    console.log(Component, 'ComponentComponent')
    return () => {
        const nav = useContext(ThemeContext);
        return <Component navigator={nav} />
    }
}

const Child = withRouter((props) => {
    console.log(props);
    return (
        <div>
            <button onClick={() => props.navigator.pushState({}, undefined, 'hello')}>
                hello
            </button>
        </div>
    )
})

高阶函数(HOC)

函数可以作为 参数 和 返回值 。

属性代理

//    CardHoc.jsx
export default function Card({ title, children }) {
    return <div>
        <h2>{ title }</h2>
        {
            children ? 
            <div>{ children }</div> : null
        }    </div>
}

export const withCard = (title) => (Component) => {
    return (props) => {
        const hocStyle = {
            margin: '12px',
            padding: '12px',
            border: '1px solid #ccc',
            borderRadius: '4px'
        }
    
        return <div style={hocStyle}>
            <h2>{title}</h2>
            <Component {....props} />
        </div>
    }
}

//    App.jsx
const Text = ({ num }) => <div>{num}</div>
const CardText = withCard('TextCard')(Text);
<CardText num={100} />

反向继承

import { Component } from 'react';

//    比如我们有一个案例: 我们需要优雅的实现 曝光埋点
/**
 * 有个按钮,我们想知道这个按钮在线上的漏斗转换
 * 每次按钮点击时,记录一个sendLog('my_btn_click'), 其实就是触发一条请求
 * 每次按钮出现时,记录一个sendLog('my_btn_show')
 * 那我的转化,pv('my_btn_click') / pv('my_btn_show')
 */

export default function Extending() {
    return (
        <div><LogIndex /></div>
    )
}

function logProps(logMap) {
    return (WrapperComponent) => {
        const didMount = WrapperComponent.prototype.componentDidMount;
        return class A extends WrapperComponent {
            componentDidMount() {
                if (didMount) {
                    didMount.apply(this);
                }
                
                Object.entries(logMap).forEach([k, v] => {
                    if (document.getElementById(k)) {
                        console.log('事件曝光', v);
                    }
                })
            }
            
            render() {
                return super.render();
            }
        }
    }
}
class Index extends Component {
    render() {
        <div>
            <div id="my_text">这是一个文字信息</div>
            <button id="my_btn">这是一个按钮</button>
        </div>
    }
}

const LogIndex = logProps({
    my_text: 'my_text_show',
    my_btn: 'my_btn_show'
})(Index)

渲染优化

类组件 类似于useMemo

import React, { Component } from 'react'
export default class renderControl extends Compoent {
    
    constructor(props) {
        super(props);
        this.state = {
            num: 0,
            count: 0
        }
        
        this.component = <Child num={this.state.num}>
    }
    
    controlRender = () => {
        const { props } = this.component;
        if (props.num !== this.state.num) {
            return this.component = React.cloneElement(
                this.component,
                { num: this.state.num }
            )
        }
    }
    
    render() {
        
        const { num, count } = this.state;
        
        return <div>
            {this.controlRender()}
            <button onClick={() => this.setState({ num: num + 1 })}>{num}</button>    
            <button onClick={() => this.setState({ count: count + 1 })}>{count}</button>    
        </div>
    }
}

const Child = ({ num }) => {
    console.log('子组件执行');
    return <div>{ num }</div>
}

函数组件 - useMemo

import React, { Component, useState } from 'react'
export default function renderControl() {
    
    const [ num, setNum ] = useState(0);
    const [ count, setCount ] = useState(0);
    
    return <div>
            {useMemo(() => <Child num={num} />, [num])}
            <button onClick={() => this.setState({ num: num + 1 })}>{num}</button>    
            <button onClick={() => this.setState({ count: count + 1 })}>{count}</button>    
        </div>

    
}

const Child = ({ num }) => {
    console.log('子组件执行');
    return <div>{ num }</div>
}


useMemo

函数:返回值进行缓存;
Deps: 依赖项改变了,我就再次执行;

useCallback

函数:函数进行缓存
Deps: 依赖项改变了,我就再次执行;

import React, { useCallback, useState } from 'react';

export default function RenderControl() {
    
    const [num, setNum] = useState(0);
    const [count, setCount] = useState(0);
    
    const handleChange = useCallback(() => {
        setCount(count => count + 1);
    }, [])
    
    return (
        <div>
            <MemoChild onChange={handleChange} />
            <button onClick={() => setNum(num + 1)}>{num}</button>
            <button onClick={() => setCount(count + 1)}>{count}</button>
        </div>
    )
}

const Child = ({ num, onChange }) => {
    console.log('子组件执行');
    return <div>
        <button onClick={() => onChange()}>
            onChange
        </button>
    </div>
}

const MemoChild = React.memo(Child);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1603348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

获取公募基金持仓【数据分析系列博文】

摘要 从指定网址获取公募基金持仓数据&#xff0c;快速解析并存储数据。 &#xff08;该博文针对自由学习者获取数据&#xff1b;而在投顾、基金、证券等公司&#xff0c;通常有Wind、聚源、通联等厂商采购的数据&#xff09; 1. 导入必要的库&#xff1a; pandas 用于数据处理…

「Qt Widget中文示例指南」如何实现行编辑功能

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 Line Edits&#xf…

后端插入数据库问题

IDEA报错&#xff1a;Error updating database. Cause: java.sql.SQLException: Column count doesn’t match value count at row 1 1、看报错消息&#xff0c;SQLException&#xff0c;定位到SQL语句问题 并且看best guess最好猜测&#xff0c;再去找路径下的ShoppingCartMa…

React-基础语法学习

1、教程&#xff1a;井字棋游戏 本教程将引导你逐步实现一个简单的井字棋游戏&#xff0c;并且不需要你对 React 有任何了解。在此过程中你会学习到一些编写 React 程序的基本知识&#xff0c;完全理解它们可以让你对 React 有比较深入的理解。 1.1、教程分成以下几个部分&am…

Hudi-IDEA编程

项目 一、HudiSparkKafka&#xff08;Scala&#xff09; 配置详见【1.Scala配置】 依赖详见【1.HudiSparkKafka依赖】 1-1 构建SparkSession对象 def main(args: Array[String]): Unit {//1.构建SparkSession对象val spark: SparkSession SparkUtils.createSparkSession(…

社交媒体数据恢复:YY语音

YY语音数据恢复指南 在我们的日常生活中&#xff0c;数据丢失是一种常见的现象。有时候&#xff0c;我们可能会不小心删除了重要的文件&#xff0c;或者因为硬件故障而导致数据丢失。在这种情况下&#xff0c;数据恢复软件可以帮助我们找回丢失的数据。本文将重点介绍如何使用Y…

手机拍照技术

拍照技巧 说明: 本文将主要介绍摄影和手机常见技巧&#xff1b; 1. 摄影的基本知识 **说明&#xff1a;**关于摄影&#xff0c;手机和相机的原理都是相同的&#xff0c;不同的是相机在很多方面优于手机&#xff0c;但是专业的设备对于我们这种的非专业的人来说&#xff0c;刚…

MAC上如何将某个目录制作成iso格式磁盘文件,iso文件本质是什么?以及挂载到ParallelDesktop中?(hdiutil makehybrid )

背景 ParallelsDesktop没有安装ParallelsTools的无法共享目录&#xff0c;可以通过ParallelsDesktop提供CD磁盘的方式共享进去 命令 # 准备文档 mkdir mytestdir cp xxx mytestdir# 生成iso hdiutil makehybrid -o output.iso mytestdir -iso -joliethdiutil是MAC提供的磁盘…

linux 修改 root 密码

1、先重启 2、看到下面的界面&#xff0c;按上下箭头&#xff0c;然后按 e 键。 3、进入该界面&#xff0c;按界面步骤操作 4、按ctrlx&#xff0c;进入到下面的界面&#xff0c;依次输入下面的指令即可 mount -o remount,rw /sysroot #让sysroot 能读写chroot /sysroot #切换到…

校园综合服务平台V3.9.2 源码修复大部分已知BUG

校园综合服务平台&#xff0c;版本更新至V3.9.1 &#xff0c;源码功能强大&#xff0c;ui 精美&#xff0c; 功能包含但不限于校园跑腿&#xff0c;外卖&#xff0c;组局&#xff0c;圈子&#xff0c;商城&#xff0c;抽奖&#xff0c;投票&#xff0c;团购&#xff0c;二手市场…

Python中2种常用数据可视化库:Bokeh和Altair

本文分享自华为云社区《探究数据可视化&#xff1a;Bokeh vs. Altair》&#xff0c;作者&#xff1a;柠檬味拥抱。 在数据科学和数据分析领域&#xff0c;数据可视化是一种强大的工具&#xff0c;可以帮助我们更好地理解数据、发现模式和趋势。Python作为一种流行的数据科学工…

【QT进阶】Qt Web混合编程之QWebEngineView基本用法

往期回顾 【QT入门】Qt自定义控件与样式设计之自定义QTabWidget实现tab在左&#xff0c;文本水平的效果-CSDN博客【QT进阶】Qt Web混合编程之CEF、QCefView简单介绍-CSDN博客 【QT进阶】Qt Web混合编程之VS2019 CEF的编译与使用-CSDN博客 【QT进阶】Qt Web混合编程之QWebEngi…

(十四)C++自制植物大战僵尸游戏windows平台视频播放实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs VLC库 在Cocos2d-x游戏开发框架中&#xff0c;没有实现windows平台视频播放的功能&#xff0c;需要自定义实现。在本项目中使用vlc库实现windows平台的视频播放功能。 vlc官网&#xff1a;网址 下载完成后&#x…

.net反射(Reflection)

文章目录 一.概念&#xff1a;二.反射的作用&#xff1a;三.代码案例&#xff1a;四.运行结果&#xff1a; 一.概念&#xff1a; .NET 反射&#xff08;Reflection&#xff09;是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射&#xff0c;你可…

分布式搭载博客网站

一.运行环境&#xff1a; IP主机名系统服务192.168.118.128Server-WebLinuxWeb192.168.118.131Server-NFS-DNSLinuxNFS/DNS 二.基础配置 1. 配置主机名&#xff0c;hosts映射 [rootserver ~]# hostnamectl set-hostname Server-Web [rootserver ~]# hostname Server-Web [r…

每日算法4/17

1552. 两球之间的磁力 题目 在代号为 C-137 的地球上&#xff0c;Rick 发现如果他将两个球放在他新发明的篮子里&#xff0c;它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子&#xff0c;第 i 个篮子的位置在 position[i] &#xff0c;Morty 想把 m 个球放到这些篮子里&…

目标检测——行人交通信号灯数据集

一、重要性及意义 行人交通信号灯检测的重要性及意义主要体现在以下几个方面&#xff1a; 首先&#xff0c;行人交通信号灯检测对于提高道路安全性至关重要。通过准确识别交通信号灯的状态&#xff0c;行人可以更加清晰地了解何时可以安全地过马路&#xff0c;从而避免与车辆…

《ElementPlus 与 ElementUI 差异集合》el-popconfirm 气泡确认框之插槽写法有差异

ElementUI 直接在 el-button 上配置属性 slot&#xff1b; <el-popconfirm title"确定删除吗&#xff1f;请谨慎操作&#xff01;" confirm"delete"><el-button slot"reference" size"small" type"danger">删…

C++stack oj题目详解

1. 最小栈 155. 最小栈 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop() 删除堆栈顶部的元素。 int top() 获取…

【Git】git命令大全(持续更新)

本文架构 0.描述git简介术语 1.常用命令2. 信息管理新建git库命令更改存在库设置获取当前库信息 3.工作空间相关将工作空间文件添加到缓存区&#xff08;增&#xff09;从工作空间中移除文件&#xff08;删&#xff09;撤销提交 4.远程仓库相关同步远程仓库分支 &#xff08;持…