React在构建高性能前端应用时有哪些最佳实践?

2026-06-10 09:162阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1623个文字,预计阅读时间需要7分钟。

React在构建高性能前端应用时有哪些最佳实践?

目录

1.前言

2.useState

3.useEffect

4.useLayoutEffect

5.useMemo

6.useCallback

7.useRef

8.useReducer

9.useContext

10.memo

前言

React 16.8 推出 hooks,为函数组件提供了更好的状态管理和副作用处理,使函数组件更易于代码复用和编写。以下是对各个 hooks 的简要介绍。

2. useStateuseState 允许你在函数组件中添加状态(state),使得组件可以响应状态的变化。

3. useEffectuseEffect 允许你在函数组件中执行副作用操作,如数据获取、订阅或手动更改 DOM。

4. useLayoutEffectuseLayoutEffect 和 useEffect 类似,但它的副作用操作会在浏览器布局之前执行,适用于需要同步更新的场景。

5. useMemouseMemo 用于缓存计算结果,避免不必要的计算。

React在构建高性能前端应用时有哪些最佳实践?

6. useCallbackuseCallback 用于缓存函数,避免在每次渲染时都创建新的函数实例。

7. useRefuseRef 允许你在函数组件中访问一个可变的、引用类型(ref)的变量,该变量在组件的整个生命周期内保持不变。

8. useReduceruseReducer 允许你将复杂的状态逻辑提取到可复用的 reducer 函数中,适用于状态逻辑复杂或多个子组件需要共享状态的情况。

9. useContextuseContext 提供了一个机制,使得组件可以订阅 context 的变化,并获取 context 中的值。

10. memomemo 是一个高阶组件,用于优化渲染性能,它通过比较 props 和 state 来避免不必要的渲染。

目录
  • 1. 前言
  • 2. useState
  • 3. useEffect
  • 4. useLayoutEffect
  • 5. useMemo
  • 6. useCallback
  • 7. useRef
  • 8. useReducer
  • 9. useContext
  • 10. memo

1. 前言

react16.8推出hooks更好的支持函数组件,使用函数组件更容易进行代码的复用,拓展性更强。

2. useState

useState类似于class组件的state功能,用于更新视图

import React, { Component, useState } from 'react'; export default function Hello() { const [count, setCount] = useState(0); //设置默认值为0 return <div> {count} <button onClick={()=>setCount(count + 1)}>增加</button> </div> } //useState还可以使用函数进行赋值 const [count, setCount] = useState(()=>0); //设置默认值为0

3. useEffect

useEffect接受两个参数,第一个参数是要执行的回调函数,第二个参数是依赖的参数,如下面的例子里只有当count发生变化的时候才会打印count,当第二个参数为空数组的时候,组件在渲染完成后会执行一次,第二个参数不传递的时候每次渲染都会执行

export default function Hello() { const [count, setCount] = useState(() => 0); //设置默认值为0 // useEffect useEffect(() => { }, [count]) return <div> {count} <button onClick={() => setCount(count + 1)}>增加</button> </div> }

带有返回值的useEffect用于清除执行过程中的副作用

useEffect(()=>{ const timer = setInterval(() => { console.log(count); }, 1000); window.addEventListener('resize',handleResize); return function(){ clearInterval(timer); window.removeEventListener('resize',handleResize); } }, [count])

如果每次执行useEffect都定义一个定时器,那定时器会越来越多,通过在返回函数中清除定时器取消这个副作用。useEffect返回函数的执行时机是下一次useEffect执行之前。

利用这一点可以实现防抖和节流函数

4. useLayoutEffect

dom渲染之前的useEffect: useLayoutEffect =》 dom渲染 =》useLayout

export default function Hello (props){ const [count, setCount] = useState(0); useEffect(()=>{ console.log('useEffect'); },[count]); useLayoutEffect(()=>{ console.log('useLayoutEffect'); },[count]) return <div> {count} <button onClick={()=> setCount(count+1)}>增加</button>; </div> }

使用useEffect和useLayoutEffect去更新视图状态会产生不同的效果,useEffect会有一个状态到另一个状态的过程(闪动效果),useLayoutEffect直接渲染最终状态

5. useMemo

useMemo的作用就是缓存,减少代码的执行次数。

下面的代码点击按钮count状态发生变化,整个Hello函数体内的代码都会执行,每次点击按钮都会打印str的值

export default function Hello (props){ const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); useEffect(()=>{ console.log('useEffect'); },[count]); console.log('str'); //每次渲染都会执行 return <div> {count} {str} <button onClick={()=> setCount(count+1)}>增加</button> </div> }

使用useMemeo进行缓存,当str发生变化的时候再执行打印语句

useMemo(()=>{ console.log(str); },[str])

useMemo还可以用来缓存函数

export default function Hello (props){ const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); useEffect(()=>{ console.log('useEffect'); },[count]); // 使用useMemo缓存函数 const hanldeClick = useMemo(()=>{ return function(){ console.log(count); }; },[count]); return <div> {count} {str} <button onClick={()=> setCount(count+1)}>增加</button> <button onClick={hanldeClick}>测试</button> </div> }

6. useCallback

useCallback的功能是缓存函数,取的是useMemo的运行结果

const handleClick = useMemo(()=>{ return function(){ console.log(count); }; },[count]); const handleClick = useCallback(()=>{ console.log(count); },[count])

上面两个实现的功能是一样的,在平时的开发中要尽量使用useMemo去缓存函数

7. useRef

  • 获取元素dom ref.current
  • 缓存数据

使用useRef获取元素

export default function Hello(props) { const ref = useRef(null); useEffect(() => { console.log(ref.current); // <input id='input'> }) return <div> <input ref={ref} id="input" /> </div> }

使用useRef保存数据,当ref.current发生变化的时候视图不会重新渲染

export default function Hello(props) { const ref = useRef(null); useEffect(() => { ref.current = 'hello hooks!'; }); return <div> <span> {ref.current}</span> </div> }

8. useReducer

useReducer用于更新复杂的state提升渲染性能,使用方法与redux类似。与redux的区别是redux管理的是全局的数据做数据共享,useReducer是useState的替代方案,只管理单个组件的状态。

onst reducer = (state, action) => { switch (action.name) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: return state; } }; const initState = { count: 0 }; export default function Hello() { const [state, dispatch] = useReducer(reducer, initState) return <div> <span> {state.count}</span> <button onClick={() => dispatch({ name: 'increment' })}>增加</button> <button onClick={() => dispatch({ name: 'decrement' })}>减少</button> </div> }

9. useContext

useContext用来解决props层层传递,嵌套很深的问题。

export default function Father() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { setCount(count + 1); }, [count]); return <div> {count} <button onClick={() => handleClick()}>增加</button> <MyContext.Provider value={{ count }}> <Children /> </MyContext.Provider> </div> }; function Children() { const context = useContext(MyContext); return <div> 父组件的count: {context.count} </div> };

10. memo

在calss组件中通过对比props,子组件接收的props发生变化的时候才进行更新渲染,在函数组件中没有识别props的能力,当父组件重新渲染的时候子组件也会重新渲染,在使用memo包裹后只有props发生变化的时候才会重新渲染。memo的功能类似于calss组件对pureComponent对props进行了浅比较。

export default function Father() { const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); return <div> {count} {str} <button onClick={() => setCount(count + 1)}>增加count</button> <button onClick={() => setStr(str + 1)}>修改str</button> <Children count={count} /> </div> }; const Children = React.memo(function Children(props) { console.log('子组件渲染'); return <div> 子组件: {props.count} </div> } );

上面的例子中,count变化的时候子组件渲染更新,str变化的时候子组件不重新渲染。

到此这篇关于React hooks使用方法全面汇总的文章就介绍到这了,更多相关React hooks内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!

本文共计1623个文字,预计阅读时间需要7分钟。

React在构建高性能前端应用时有哪些最佳实践?

目录

1.前言

2.useState

3.useEffect

4.useLayoutEffect

5.useMemo

6.useCallback

7.useRef

8.useReducer

9.useContext

10.memo

前言

React 16.8 推出 hooks,为函数组件提供了更好的状态管理和副作用处理,使函数组件更易于代码复用和编写。以下是对各个 hooks 的简要介绍。

2. useStateuseState 允许你在函数组件中添加状态(state),使得组件可以响应状态的变化。

3. useEffectuseEffect 允许你在函数组件中执行副作用操作,如数据获取、订阅或手动更改 DOM。

4. useLayoutEffectuseLayoutEffect 和 useEffect 类似,但它的副作用操作会在浏览器布局之前执行,适用于需要同步更新的场景。

5. useMemouseMemo 用于缓存计算结果,避免不必要的计算。

React在构建高性能前端应用时有哪些最佳实践?

6. useCallbackuseCallback 用于缓存函数,避免在每次渲染时都创建新的函数实例。

7. useRefuseRef 允许你在函数组件中访问一个可变的、引用类型(ref)的变量,该变量在组件的整个生命周期内保持不变。

8. useReduceruseReducer 允许你将复杂的状态逻辑提取到可复用的 reducer 函数中,适用于状态逻辑复杂或多个子组件需要共享状态的情况。

9. useContextuseContext 提供了一个机制,使得组件可以订阅 context 的变化,并获取 context 中的值。

10. memomemo 是一个高阶组件,用于优化渲染性能,它通过比较 props 和 state 来避免不必要的渲染。

目录
  • 1. 前言
  • 2. useState
  • 3. useEffect
  • 4. useLayoutEffect
  • 5. useMemo
  • 6. useCallback
  • 7. useRef
  • 8. useReducer
  • 9. useContext
  • 10. memo

1. 前言

react16.8推出hooks更好的支持函数组件,使用函数组件更容易进行代码的复用,拓展性更强。

2. useState

useState类似于class组件的state功能,用于更新视图

import React, { Component, useState } from 'react'; export default function Hello() { const [count, setCount] = useState(0); //设置默认值为0 return <div> {count} <button onClick={()=>setCount(count + 1)}>增加</button> </div> } //useState还可以使用函数进行赋值 const [count, setCount] = useState(()=>0); //设置默认值为0

3. useEffect

useEffect接受两个参数,第一个参数是要执行的回调函数,第二个参数是依赖的参数,如下面的例子里只有当count发生变化的时候才会打印count,当第二个参数为空数组的时候,组件在渲染完成后会执行一次,第二个参数不传递的时候每次渲染都会执行

export default function Hello() { const [count, setCount] = useState(() => 0); //设置默认值为0 // useEffect useEffect(() => { }, [count]) return <div> {count} <button onClick={() => setCount(count + 1)}>增加</button> </div> }

带有返回值的useEffect用于清除执行过程中的副作用

useEffect(()=>{ const timer = setInterval(() => { console.log(count); }, 1000); window.addEventListener('resize',handleResize); return function(){ clearInterval(timer); window.removeEventListener('resize',handleResize); } }, [count])

如果每次执行useEffect都定义一个定时器,那定时器会越来越多,通过在返回函数中清除定时器取消这个副作用。useEffect返回函数的执行时机是下一次useEffect执行之前。

利用这一点可以实现防抖和节流函数

4. useLayoutEffect

dom渲染之前的useEffect: useLayoutEffect =》 dom渲染 =》useLayout

export default function Hello (props){ const [count, setCount] = useState(0); useEffect(()=>{ console.log('useEffect'); },[count]); useLayoutEffect(()=>{ console.log('useLayoutEffect'); },[count]) return <div> {count} <button onClick={()=> setCount(count+1)}>增加</button>; </div> }

使用useEffect和useLayoutEffect去更新视图状态会产生不同的效果,useEffect会有一个状态到另一个状态的过程(闪动效果),useLayoutEffect直接渲染最终状态

5. useMemo

useMemo的作用就是缓存,减少代码的执行次数。

下面的代码点击按钮count状态发生变化,整个Hello函数体内的代码都会执行,每次点击按钮都会打印str的值

export default function Hello (props){ const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); useEffect(()=>{ console.log('useEffect'); },[count]); console.log('str'); //每次渲染都会执行 return <div> {count} {str} <button onClick={()=> setCount(count+1)}>增加</button> </div> }

使用useMemeo进行缓存,当str发生变化的时候再执行打印语句

useMemo(()=>{ console.log(str); },[str])

useMemo还可以用来缓存函数

export default function Hello (props){ const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); useEffect(()=>{ console.log('useEffect'); },[count]); // 使用useMemo缓存函数 const hanldeClick = useMemo(()=>{ return function(){ console.log(count); }; },[count]); return <div> {count} {str} <button onClick={()=> setCount(count+1)}>增加</button> <button onClick={hanldeClick}>测试</button> </div> }

6. useCallback

useCallback的功能是缓存函数,取的是useMemo的运行结果

const handleClick = useMemo(()=>{ return function(){ console.log(count); }; },[count]); const handleClick = useCallback(()=>{ console.log(count); },[count])

上面两个实现的功能是一样的,在平时的开发中要尽量使用useMemo去缓存函数

7. useRef

  • 获取元素dom ref.current
  • 缓存数据

使用useRef获取元素

export default function Hello(props) { const ref = useRef(null); useEffect(() => { console.log(ref.current); // <input id='input'> }) return <div> <input ref={ref} id="input" /> </div> }

使用useRef保存数据,当ref.current发生变化的时候视图不会重新渲染

export default function Hello(props) { const ref = useRef(null); useEffect(() => { ref.current = 'hello hooks!'; }); return <div> <span> {ref.current}</span> </div> }

8. useReducer

useReducer用于更新复杂的state提升渲染性能,使用方法与redux类似。与redux的区别是redux管理的是全局的数据做数据共享,useReducer是useState的替代方案,只管理单个组件的状态。

onst reducer = (state, action) => { switch (action.name) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: return state; } }; const initState = { count: 0 }; export default function Hello() { const [state, dispatch] = useReducer(reducer, initState) return <div> <span> {state.count}</span> <button onClick={() => dispatch({ name: 'increment' })}>增加</button> <button onClick={() => dispatch({ name: 'decrement' })}>减少</button> </div> }

9. useContext

useContext用来解决props层层传递,嵌套很深的问题。

export default function Father() { const [count, setCount] = useState(0); const handleClick = useCallback(() => { setCount(count + 1); }, [count]); return <div> {count} <button onClick={() => handleClick()}>增加</button> <MyContext.Provider value={{ count }}> <Children /> </MyContext.Provider> </div> }; function Children() { const context = useContext(MyContext); return <div> 父组件的count: {context.count} </div> };

10. memo

在calss组件中通过对比props,子组件接收的props发生变化的时候才进行更新渲染,在函数组件中没有识别props的能力,当父组件重新渲染的时候子组件也会重新渲染,在使用memo包裹后只有props发生变化的时候才会重新渲染。memo的功能类似于calss组件对pureComponent对props进行了浅比较。

export default function Father() { const [count, setCount] = useState(0); const [str, setStr] = useState('hello hooks!'); return <div> {count} {str} <button onClick={() => setCount(count + 1)}>增加count</button> <button onClick={() => setStr(str + 1)}>修改str</button> <Children count={count} /> </div> }; const Children = React.memo(function Children(props) { console.log('子组件渲染'); return <div> 子组件: {props.count} </div> } );

上面的例子中,count变化的时候子组件渲染更新,str变化的时候子组件不重新渲染。

到此这篇关于React hooks使用方法全面汇总的文章就介绍到这了,更多相关React hooks内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!