当前位置: 首页 > news >正文

React 基础

对比学习react, 以vue 为例
Vue3 的双向绑定: state.xxx = xxx => Proxy set => trigger(触发更新) => effect (执行副作用函数) => 更新dom
React(类组件):onClick => dispatch => enqueueSetState(更新队列) => scheduleUpdateOnFiber(标记fiber节点,启动更新)
学习的时候尽量结合ts一起

  • 类组件与函数组件(函数组件的开发效率更高,用的也更多一些)

  • 类组件:

      interface AppState {name: string,value: string}class App extends React.Component<AppState> {state:AppState = {name:'react',value: '类组件'};render():React.ReactNode {return <div>{`我是${this.state.name + this.state.value}`}</div>}}```
    
  • 函数组件:

      	interface AppState {name: string,value: string}const App = () => {const [myState, setState] = useState<AppState>({name: 'react', value : '函数组件'})return (<div className="content"><h1>Rsbuild with React</h1><p>{`我是${myState.name + myState.value}`}</p></div>);};
    
  • 受控组件与非受控组件(以表单元素举例,自定义组件也适用)

    • 受控组件(指表单元素的值由React组件的state完全控制的组件)
      const App= () => {const [name, setName] = useState<string>('')const handleChange = ():void => {setName('张三')}return (<div className="content"><input value={name} onClick={handleChange}></input></div>);
      };
      
    • 非受控组件(表单元素的值由DOM自身管理,而不是由React state控制的组件)
      const App= () => {const inputRef = useRef<HTMLInputElement>(null);const handleChange = ():void => {console.log(inputRef.current?.value)}return <div><input ref={inputRef}></input><button onClick={handleChange}>获取input值</button></div>
      };
  • props 与 state

    interface PersonState {name: string,age: number,
    }
    interface PersonComProps {person: PersonState
    }
    //props 外部传入使用
    const PersonCom:React.FC<PersonComProps> = (props) => {return <div><span>姓名: {props.person.name}</span><span>年龄:{props.person.age}</span></div>
    }
    const App= () => {//通过useState hooks 声明stateconst [person, setPerson] = useState<PersonState>({name: '张三',age: 18})const changePerson = ():void => {setPerson({name: '王五',age: 20})}return <div><PersonCom person ={person}  /><button onClick={changePerson}>切换人物</button></div>
    };
    
  • 条件渲染与列表(React 非常灵活,编写jsx的时候可以就当作我们在写js)

    	interface User {name: string}const App = () => {const [show, setShow] = useState<boolean>(true);const [list] = useState<User[]>([{name:'张三'},{name:'李四'},{name:'王五'}])const handleChange = (): void => {setShow(!show);};return (<div>{/* 三元判断渲染 */}<div>{show ? "展示这个" : "展示另一个"}</div><button onClick={handleChange}>切换展示</button>{/* list循环渲染 */}{list.map((item,index) => <div key={index}>{item.name}</div>)}</div>);};
    
  • React 生命周期(这里描述的是19版本的类组件; 函数组件大多数使用useEffect、useMemo等hooks模拟生命周期操作)

    • 挂载阶段
      • constructor (初始化数据)
        1. 调用 super(props) 继承React组件
        2. 初始化组件的state状态
        3. 为方法绑定this上下文(解决this指向问题)
        4. 创建ref引用等准备工作
      • static getDerivedStateFromProps(在渲染前根据新的props来更新state)
        1. 本质上是一个静态函数 传入state 和 props ,返回值会和当前的state 合并
      • render(渲染)
        1. 返回JSX描述UI结构
        2. 必须是纯函数,不能修改state或与DOM交互
        3. 准备虚拟DOM,为后续的DOM更新做准备
      • componentDidMount(组件挂载完成, 这里一般可以请求接口)
    • 更新阶段
      • static getDerivedStateFromProps
      • shouldComponentUpdate(是否应该更新)
        1. 比较新旧props和state
        2. 返回true允许更新,返回false阻止更新
        3. 性能优化操作
      • render
      • getSnapshotBeforeUpdate(获取更新前快照,React更新过程中会通过计算虚拟dom去更新真实dom,这使得我们会丢失一些想保存的状态,例如聊天室中当前的滚动位置,可以通过此声明周期将位置信息传给 componentDidUpdate)
        // 在聊天室中,新消息到来时保持当前滚动位置
        getSnapshotBeforeUpdate(prevProps, prevState) {if (prevProps.messages.length < this.props.messages.length) {// 捕获滚动容器的滚动高度return this.chatContainer.scrollHeight - this.chatContainer.scrollTop;}return null;
        }componentDidUpdate(prevProps, prevState, snapshot) {if (snapshot !== null) {// 根据之前计算的滚动位置调整UIthis.chatContainer.scrollTop = this.chatContainer.scrollHeight - snapshot;}
        }
        
      • componentDidUpdate(更新完成)
    • 卸载阶段
      • componentWillUnmount(组件将要卸载)
        1. 事件监听函数/定时器的销毁操作
      • static getDerivedStateFromError (捕获子组件的渲染错误)
      • componentDidCatch (捕获子组件的js错误)
        1. 异常兜底操作,防止白屏
  • React 事件相关

    • 阻止默认事件: e.preventDefault();
    • 阻止事件传播: stopPropagation();
    • dom绑定事件
      const handleListen = (): void => {console.log('focus了')};useEffect(() => {inputRef.current?.addEventListener("focus", handleListen);return () => {inputRef?.current?.removeEventListener("focus", handleListen);};}, []);
    
    • 自定义DOM事件
      • 使用new CustomEvent来创建自定义事件
      • 使用document.dispatchEvent 触发自定义事件
    const App = () => {//自定义事件hooksconst useCustomEvent = (eventName: string, detail: any) => {const dispathEvent = useCallback((customDetail?: any) => {const event = new CustomEvent(eventName, {detail: customDetail || detail,});document.dispatchEvent(event);},[eventName, detail]);return dispathEvent;};const dispathMyEvent = useCustomEvent("myEvent", "hello word");const handleMyEvent = (): void => {console.log("触发了自定义事件");};useEffect(() => {//监听事件document.addEventListener("myEvent", handleMyEvent);return () => {document.removeEventListener("myEvent", handleMyEvent);};}, []);return (<div>{/* //触发自定义事件 */}<button onClick={() => dispathMyEvent()}>触发自定义事件</button></div>);
    };

文章转载自:

http://UgAgV67j.qcztm.cn
http://tiCNUYeh.qcztm.cn
http://DZ3qvyE7.qcztm.cn
http://c9PCgtd5.qcztm.cn
http://attVbfH4.qcztm.cn
http://yBbFBWjT.qcztm.cn
http://MG9WQIE6.qcztm.cn
http://BbOXnYME.qcztm.cn
http://gyb7EERq.qcztm.cn
http://FqQYxLgx.qcztm.cn
http://PE45Y437.qcztm.cn
http://0SYKirpU.qcztm.cn
http://YLbtNosL.qcztm.cn
http://pKAaM5eh.qcztm.cn
http://kEt9DfyL.qcztm.cn
http://CqdrZgJd.qcztm.cn
http://NeoqomTJ.qcztm.cn
http://AtrIPYTE.qcztm.cn
http://1SA8w2OZ.qcztm.cn
http://yWnRQMxz.qcztm.cn
http://oMHPPGMH.qcztm.cn
http://U3Uyh2Wo.qcztm.cn
http://VI6eCpKs.qcztm.cn
http://OADYzKov.qcztm.cn
http://Kik6w1rp.qcztm.cn
http://bV7GwsXL.qcztm.cn
http://eIx2SypW.qcztm.cn
http://OHm7D42b.qcztm.cn
http://Ngh7jVUm.qcztm.cn
http://eLVwfcFk.qcztm.cn
http://www.dtcms.com/a/377873.html

相关文章:

  • 自动化SSL证书管理:应对域名SSL证书更新焦虑
  • 跨平台快速上手:Couchbase 安装与使用指南
  • 【译】Visual Studio 八月更新已发布 —— 更智能的人工智能、更出色的调试功能以及更多控制权
  • python+selenium+PO模式
  • Excel表格如何制作?【图文详解】表格Excel制作教程?电脑Excel表格制作?
  • 【基于CNN的57类交通标志识别系统】
  • 【深度学习新浪潮】Nano Banana(Gemini 2.5 Flash Image)技术解析与开发者实操指南
  • 【Qt开发】显示类控件(二)-> QLCDNumber
  • 三角孔径衍射误差难分析?OAS 软件深度仿真解难题
  • 鸿蒙Next Web组件生命周期详解:从加载到销毁的全流程掌控
  • 【从0开始学习Java | 第17篇】集合(中-Set部分)
  • 【AI指导】Python实现prophet模型的业绩预测
  • RPA-4.0.0.0_SAAS新版本已上线,Edge扩展自动安装,快速实现RPA流程自动化
  • Server 13 ,CentOS 上使用 Nginx 部署多个前端项目完整指南( 支持多端口与脚本自动化 )
  • Java后端测试
  • Skywork-OR1:昆仑万维开源的数学代码推理系列模型
  • 【Linux】基本指令 · 上
  • OBS插件详细教程:OBS美颜插件下载,OBS美颜插件怎么用?
  • 如何在 Spring Boot 中指定不同的配置文件?
  • spring boot 拦截器增加语言信息
  • leedcode 算法刷题第三十二天
  • CentOS 7 下iscsi存储服务配置验证
  • 求解指定泛函的驻点所满足的偏微分方程及边界条件
  • 股指期货保证金一手需要多少钱?
  • LVS与Keepalived详解(一)负载均衡集群介绍
  • 【Proteus仿真】按键控制系列仿真——LED灯表示按键状态/按键控制LED灯/4*4矩阵键盘控制LED
  • 【前沿技术拓展Trip one】 芯片自动化和具身智能
  • javaEE之线程初步认识
  • `struct iovec`详解
  • python超市购物 2025年6月电子学会python编程等级考试一级真题答案解析