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

个人网站 虚拟主机价格年报申报入口官网

个人网站 虚拟主机价格,年报申报入口官网,wordpress pdf view,建设门户网站系统的必要性目录 一、React生命周期图例1. 挂载/创建阶段(组件首次渲染)4步2. 更新阶段(props/state变更)5步3. 卸载阶段(组件从DOM移除)4. 错误处理(React 16新增) 二、Hooks 对生命周期的替代…

目录

  • 一、React生命周期图例
    • 1. 挂载/创建阶段(组件首次渲染)4步
    • 2. 更新阶段(props/state变更)5步
    • 3. 卸载阶段(组件从DOM移除)
    • 4. 错误处理(React 16+新增)
  • 二、Hooks 对生命周期的替代
    • 1. 状态管理(替代 this.state)
    • 2. 副作用管理(替代生命周期钩子)
    • 3. 性能优化(替代 shouldComponentUpdate)
    • 4. 其他常用数据保存 Hooks
  • 三、hooks其他问题
    • 1. useEffect 与 useLayoutEffect 的区别?
    • 2. 如何避免 useEffect 无限循环?
    • 3. constructor 和 getDerivedStateFromProps 的区别
    • 4. useState和useReducer
    • 5. 多个 useEffect 的执行顺序
    • 6. 如何避免 useEffect 无限循环
    • 7. useMemo和 React.memo
    • 8. 自定义React hooks
    • 9. setState和useState是同步还是异步?区别是什么?

一、React生命周期图例

在这里插入图片描述

函数何时调用其他典型场景hooks等效实现
constructor仅在组件实例化时执行一次唯一可以直接修改state,很少使用初始化内部状态相当于useState/useReducer 初始化状态
getDerivedStateFromProps外部传入属性发生变化,例如:setState(),forceUpdate()state需要从props初始化时使用,每次render都会调用。维护两者状态一致会增加复杂度,尽量不要使用表单控件获取默认值useMemo、useCallback 、useEffect+useState
shouldComponentUpdate属性变化时,除了forceUpdate()决定Virtual DOM是否要重绘性能优化React.memo,用于浅比较 props 来决定是否重新渲染组件
render渲染UI描述UI,必须写的方法函数组件本身就是渲染逻辑
getSnapshotBeforeUpdate页面render之前调用,state已更新获取render之前DOM状态使用 useLayoutEffect 在 DOM 更新前读取值,并通过 useRef 存储快照
componentDIdMountUI渲染完成后调用只执行一次发起ajax等外部请求useEffect(…, [])
componentDitUpdate每次UI更新时调用页面需要根据props变化重新获取数据useEffect(…, [dependency])
componentWillUnmount组件被移除时调用资源释放useEffect 返回的清理函数return

1. 挂载/创建阶段(组件首次渲染)4步

  • 执行顺序:constructor → getDerivedStateFromProps → render → componentDidMount

2. 更新阶段(props/state变更)5步

  • 触发条件:props 变化、state 变化、forceUpdate()
  • 执行顺序:getDerivedStateFromProps → shouldComponentUpdate → render →
    getSnapshotBeforeUpdatecomponentDidUpdate

3. 卸载阶段(组件从DOM移除)

  • componentWillUnmount:用于清理副作用(如定时器、订阅)

4. 错误处理(React 16+新增)

  • componentDidCatch

二、Hooks 对生命周期的替代

1. 状态管理(替代 this.state)

  • useState:基础状态管理。
const [count, setCount] = useState(0);
  • useReducer:复杂状态逻辑(类似 Redux 的 reducer)
const [state, dispatch] = useReducer(reducer, initialState);

2. 副作用管理(替代生命周期钩子)

  • useEffect:相当于 componentDidMount + componentDidUpdate + componentWillUnmount 的组合
// 依赖项为空数组:仅挂载时执行(类似 componentDidMount)
useEffect(() => {// 初始化逻辑return () => {// 组件卸载时执行:清理逻辑(类似 componentWillUnmount)};
}, []);// 无依赖项:每次渲染后执行(类似 componentDidMount + componentDidUpdate)
useEffect(() => {// 副作用逻辑
});// 特定依赖变化时执行
useEffect(() => {// 仅当 count 变化时执行(初始也执行一次?)
}, [count]);

3. 性能优化(替代 shouldComponentUpdate)

  • React.memo:浅比较 props,阻止重复渲染(函数组件版 PureComponent)。
const MyComponent = React.memo((props) => { ... });
  • useMemo:缓存计算结果,避免重复计算。
const expensiveValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • useCallback:缓存函数引用,避免子组件不必要的更新。
const handleClick = useCallback(() => {doSomething(a);
}, [a]);

4. 其他常用数据保存 Hooks

  • useRef:保存可变值(类似类组件的实例属性);获取 DOM 节点(替代 createRef)。
  • useContext:跨层级传递数据(替代 Context.Consumer)。

三、hooks其他问题

1. useEffect 与 useLayoutEffect 的区别?

对比useEffectuseLayoutEffect
执行时机异步执行,在浏览器渲染后触发(不阻塞页面绘制)。同步执行,在 DOM 更新后、浏览器绘制前触发(可能阻塞渲染)。
适用场景数据获取、订阅等不影响渲染的操作需要读取 DOM 布局并立即更新的场景(如测量元素尺寸、滚动位置恢复)。

2. 如何避免 useEffect 无限循环?

  • 检查依赖项:确保依赖项数组中不包含引用类型(如对象、函数),或使用 useCallback/useMemo 缓存。
  • 过滤不必要的更新:在 useEffect 内部通过条件判断过滤重复操作。
  • 使用 useRef 存储可变值:避免依赖项变化触发无限循环。

3. constructor 和 getDerivedStateFromProps 的区别

方法constructorgetDerivedStateFromProps
调用时机组件实例化时调用(初始化阶段)每次渲染前调用(初始化 + 更新阶段)
是否可以更新 state可以(通过 this.state = { … })必须返回新 state 或 null(纯函数)
是否可以访问 this可以(需先调用 super(props))不可以(静态方法,无 this)
典型用途初始化 state、绑定事件处理函数根据 props 动态更新 state(如受控组件)

注意:不能在constructor里调用 setState(此时组件尚未挂载)。用this.state = { … }赋值

4. useState和useReducer

特性useStateuseReducer
状态结构基础类型(number、string、boolean)或对象复杂对象或数组
更新逻辑直接修改(setState(newValue))通过 reducer 函数处理(纯函数)
适用场景状态逻辑简单,状态更新相互独立(如计数器、表单值)复杂状态逻辑,更新逻辑分散,需要撤销 / 重做、时间旅行调试(如多值联动、状态历史记录)
组件间共享需逐层传递 state 和 setState可结合 Context 全局共享 dispatch
调试与测试较简单更易预测(纯函数),便于测试和时间旅行调试
多次调用多次调用 setState 可能触发多次渲染(React 18 中自动批处理已优化)。单个 dispatch 触发一次更新,更适合复杂状态变更。

useReducer使用

const initialState = {loading: false,data: null,error: null
};const reducer = (state, action) => {switch (action.type) {case 'FETCH_START':return { ...state, loading: true }; // 仅更新 loadingcase 'FETCH_SUCCESS':return { ...state, loading: false, data: action.payload }; // 更新 loading 和 datacase 'FETCH_ERROR':return { ...state, loading: false, error: action.error }; // 更新 loading 和 errordefault:return state;}
};const DataFetcher = () => {const [state, dispatch] = useReducer(reducer, initialState);return (<div><button onClick={() => dispatch({ type: 'FETCH_START', payload: { id: 1 } })}>start</button>{/* 其他操作... */}</div>);
};

5. 多个 useEffect 的执行顺序

useEffect(() => {console.log(1)return () => {console.log(2)};
}, []);useEffect(() => {console.log(3);return () => {console.log(4)}
});useEffect(() => {console.log(5)return () => {console.log(6)}
}, [count]);

以上代码挂载时、卸载时、count变化时的执行顺序是什么?

  • 挂载时(首次渲染)
    输出:1 → 3 → 5

    • 第一个 useEffect(依赖项为空数组 []):仅在挂载时执行。
    • 第二个useEffect(无依赖项):在每次渲染后执行,包括首次渲染。
    • 第三个 useEffect(依赖项为 count):在首次渲染时,由于count 存在初始值(假设为 0),也会执行。
  • 卸载时
    输出 6 → 4 → 2

    • 第三个 useEffect的return(依赖 count):最先注册,最后清理(6)
    • 第二个 useEffect的return(无依赖):其次注册,其次清理(4)。
    • 第一个 useEffect的return(空依赖):最后注册,最先清理(2)。
  • count 变化时
    输出:6 → 5 → 4 → 3

    • 第三个 useEffect:
      • 清理上一次的副作用(6)。
      • 执行新的副作用(5)。
    • 第二个 useEffect:
      • 清理上一次的副作用(4)。
      • 执行新的副作用(3)。

useEffect 的清理函数(return 返回的函数)遵循 “后进先出”(LIFO) 的栈结构规则,useEffect顺序执行,遇到return后压入栈中,所以第一个useEffect的return先入栈,第三个useEffect的return最后入栈;卸载时,第三个useEffect的return先出栈执行

6. 如何避免 useEffect 无限循环

  • 无限循环的常见原因
    当 useEffect 的依赖项包含引用类型(如对象、函数)时,如果每次渲染都生成新的引用,会导致 useEffect 不断触发
  • 解决
    • ① useCallback 缓存函数引用,仅在依赖项变化时才重新创建函数

      const [count, setCount] = useState(0);// 仅当依赖项 [] 变化时才重新创建函数(这里永远不变)
      const fetchData = useCallback(() => {console.log('Fetching data...');
      }, []); // ✅ 只创建一次函数useEffect(() => {fetchData();
      }, [fetchData]); // ✅ 仅触发一次
      
    • ② useMemo 缓存计算结果,避免重复计算复杂值

      const [count, setCount] = useState(0);// 仅当 count 变化时才重新计算 expensiveValue
      const expensiveValue = useMemo(() => {return performExpensiveCalculation(count);
      }, [count]);useEffect(() => {console.log(expensiveValue);
      }, [expensiveValue]); // ✅ 仅在 count 变化时触发
      
    • ③ useRef 存储可变值,修改 ref 不会导致组件重新渲染

      const [count, setCount] = useState(0);
      const prevCountRef = useRef(0);useEffect(() => {prevCountRef.current = count; // 保存当前值
      }, [count]);const prevCount = prevCountRef.current; // 获取上一次的值
      

7. useMemo和 React.memo

关于 useMemo 和 React.memo 的区别,这是 React 性能优化中的常见问题。虽然名字相似,但它们的功能和应用场景完全不同

特性useMemoReact.memo
类型Hook(函数组件内部使用)高阶组件(包裹函数组件)
作用对象值(计算结果、函数等)组件本身
触发条件依赖项变化时重新计算props 浅比较不相等时重新渲染
应用场景避免重复计算复杂值、缓存函数引用避免组件因相同 props 重复渲染
默认行为不自动执行,需手动包裹 自动执行 props 浅比较
  • React.memo 的浅比较限制
    • 仅浅比较 props:如果 props 包含引用类型(如对象、数组),需确保引用不变。
    • 函数 props:需配合 useCallback 或 useMemo 使用,避免父组件每次渲染时创建新函数。

8. 自定义React hooks

  • 定义:自定义 Hooks 是一个函数,其名称以 use 开头,内部可以调用其他 Hooks。
  • 核心价值:复用有状态的逻辑(如订阅、动画、表单验证),同时不污染组件结构。
  • 与组件的区别:组件返回 UI,而自定义 Hooks 返回数据或副作用。

自定义 Hook 示例:

import { useState, useEffect } from 'react';
// 使用 localStorage 持久化状态
function useLocalStorage(key, initialValue) {// 1. 内部使用 useState 管理状态const [value, setValue] = useState(() => {try {const storedValue = localStorage.getItem(key);return storedValue ? JSON.parse(storedValue) : initialValue;} catch (error) {return initialValue;}});// 2. 使用 useEffect 添加副作用useEffect(() => {localStorage.setItem(key, JSON.stringify(value));}, [key, value]); // 3. 指定依赖项,控制副作用触发时机// 4. 返回状态和修改状态的函数(类似 useState),也可以返回对象或函数return [value, setValue];
}

9. setState和useState是同步还是异步?区别是什么?

特性class 组件的 setState函数组件的 useState
执行时机批量异步(多数情况下)批量异步(多数情况下)
强制同步场景1. 原生事件回调 2. setTimeout/setInterval1. 原生事件回调 2. setTimeout/setInterval
状态更新方式合并对象(this.state 是累积的)完全替换(需手动合并 setState(prev => ({…prev, key})))
多次调用行为合并为一次更新(对象浅合并)按顺序执行(函数式更新)
  • 异步机制:React 为了优化性能,会批量处理多个状态更新,因此在同一个事件循环中多次调用 setState 或 useState 可能不会立即生效。

    // Class 组件
    handleClick() {this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 输出旧值(异步更新)
    }// 函数组件
    const handleClick = () => {setCount(count + 1);console.log(count); // 输出旧值(异步更新)
    };
    
  • 同步场景

    • 原生事件回调

      // Class 组件
      componentDidMount() {document.getElementById('btn').addEventListener('click', () => {this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 输出新值(同步更新)});
      }// 函数组件
      useEffect(() => {document.getElementById('btn').addEventListener('click', () => {setCount(count + 1);console.log(count); // 输出新值(同步更新)});
      }, []);
      
    • setTimeout/setInterval 回调

      场景Class 组件的 setState函数组件的 useState
      状态更新时机立即更新(同步)不立即更新(异步)
      闭包捕获问题无(通过 this.state 获取最新值)有(闭包捕获初始值)可通过 useRef 存储可变值,使用最新状态
      多次调用合并合并为一次更新(对象浅合并)按顺序执行(函数式更新)
      渲染触发次数一次(批量处理)一次(React 18 自动批处理)

      Class 组件的setState在setTimeout中:

      class Counter extends React.Component {state = { count: 0 };handleClick = () => {setTimeout(() => {this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 输出 1(状态立即更新)this.setState({ count: this.state.count + 1 });console.log(this.state.count); // 输出 2(状态立即更新)}, 1000);};render() {console.log('Rendering...'); // 仅触发一次渲染return <button onClick={this.handleClick}>{this.state.count}</button>;}
      }
      

      函数组件的useState在setTimeout中:

      const Counter = () => {const [count, setCount] = useState(0);const handleClick = () => {setTimeout(() => {setCount(prev => prev + 1); // 使用函数式更新,获取最新状态console.log(count); // 输出 0(状态未立即更新,但更新逻辑正确)setCount(prev => prev + 1); // 基于最新状态更新,最终 count 变为 2console.log(count); // 输出 0}, 1000);};return <button onClick={handleClick}>{count}</button>;
      };
      
  • 批量更新机制的差异

    • setState:多次调用会合并对象,仅触发一次渲染。
    • useState:多次调用函数式更新会按顺序执行,触发多次渲染(React 18 中自动批处理优化为一次)。
      // Class 组件
      handleClick() {this.setState({ count: this.state.count + 1 });this.setState({ count: this.state.count + 1 }); // 合并为一次更新,最终 count 只加 1
      }
      // 函数组件(React 18 之前)
      const handleClick = () => {setCount(prev => prev + 1); // 第一次更新setCount(prev => prev + 1); // 第二次更新,最终 count 加 2
      };
      
  • 获取更新后的状态

    • Class 组件:setState使用回调函数

    • 函数组件:useState使用useEffect

      this.setState({ count: this.state.count + 1 },() => {console.log(this.state.count); // 输出新值}
      );
      const [count, setCount] = useState(0);useEffect(() => {console.log(count); // 每次 count 变化时执行
      }, [count]);const handleClick = () => {setCount(count + 1);
      };
      

文章转载自:

http://keR2rMc3.wwdLg.cn
http://xpEbHK28.wwdLg.cn
http://95GWNOT4.wwdLg.cn
http://iQOd9utZ.wwdLg.cn
http://rQwgLQGi.wwdLg.cn
http://e8LV7DiP.wwdLg.cn
http://V809rWNR.wwdLg.cn
http://jg00g5an.wwdLg.cn
http://FDI0dutH.wwdLg.cn
http://GdUuIOSa.wwdLg.cn
http://YuuxGuxz.wwdLg.cn
http://IXXC1hO1.wwdLg.cn
http://HN3L8k0V.wwdLg.cn
http://fQBpVtG1.wwdLg.cn
http://oDfgPgBi.wwdLg.cn
http://B2vNhYqX.wwdLg.cn
http://KstFKKK8.wwdLg.cn
http://K8WkvHqQ.wwdLg.cn
http://JNK1Fm40.wwdLg.cn
http://u84jFSXC.wwdLg.cn
http://cGJIkZki.wwdLg.cn
http://GEd2Ca71.wwdLg.cn
http://qrlJM2uU.wwdLg.cn
http://ct6qcOOB.wwdLg.cn
http://bFScA1wO.wwdLg.cn
http://PaJK5ZTc.wwdLg.cn
http://rTHUGaYl.wwdLg.cn
http://20MKzeQC.wwdLg.cn
http://ZFAlQFVy.wwdLg.cn
http://cPBtFjkM.wwdLg.cn
http://www.dtcms.com/wzjs/633460.html

相关文章:

  • 建设网站视频百度云盘wordpress视差插件
  • asp手机网站源码上海自助建网站
  • 不用php做网站海南网站建设介绍
  • 江西冰溪建设集团网站这几年做那个网站致富
  • 南京做南京华美整容网站建设银行嘉兴分行官方网站
  • 已有域名 搭建网站wordpress自适应手机主题
  • 东阳网站优化网络媒体广告代理
  • 企业免费网站建设网站的HTML代码
  • 云梦网站开发wordpress系统介绍
  • 淘宝客怎么做的网站推广it培训班出来现状
  • dedecms网站信息统计WordPress为啥这么慢
  • 个人网站制作申请制作网页时用的最多的图像格式
  • 安娜尔返利机器人怎么做网站手机网站设计框架
  • 天津做网站设计公司找设计网站公司
  • cms建站详细教程wordpress小程序推荐
  • 网站开发基本流程图最大的域名注册网站是那个
  • 网站建设心得体会范文网站开发静态和动态
  • seo网站建设技巧百度风云榜官网
  • wordpress 做大网站wordpress 音乐盒
  • 河南省工程建设协会网站最简单的cms网站怎么做
  • 购物类网站都有哪些模块外包seo公司
  • 南京科技网站设计有特点活动发布类网站开发
  • 工信部企业网站备案系部网站建设需求分析运行需求
  • 在线直播网站建设旅游网站开发难吗
  • 怎么做非法网站免费代理服务器ip和端口
  • 苗圃网站模版网校网站怎么做
  • 旅游网站首页图片推进网站集约化建设 网络安全
  • 加强社区网站建设成都装修设计公司推荐
  • 以什么主题做网站好珠海建网站的联系方式
  • 建设局网站作用wordpress 去除顶部