首页
统计
Search
1
TypeScript学习笔记
5 阅读
2
《被讨厌的勇气》读后感
5 阅读
3
从零开始的Vue学习
3 阅读
4
摘抄
3 阅读
5
【极客时间】玩转Git三剑客笔记
3 阅读
年度总结
学习笔记
读后感
动漫汇总
日常记录
登录
Search
标签搜索
大数据
git
加密
Vue
CTF
TypeScript
React
Augenstern
累计撰写
10
篇文章
累计收到
0
条评论
首页
栏目
年度总结
学习笔记
读后感
动漫汇总
日常记录
页面
统计
搜索到
1
篇与
React
的结果
2025-12-03
React Hook学习
参考链接: React 内置 HookHook简单介绍 定义: 以use开头的函数 作用: Hook有助于在组件中使用不同的React功能 使用: Hook比普通函数更为严格,只能在的组件(或其他 Hook)的 顶层 调用Hook 分类:State HookContext HookRef HookEffect Hook性能 Hook其他 Hook自定义 HookState Hook状态帮助组件,用于“记住”用户的输入信息useState :声明可以直接更新的状态变量示例:function MyButton(){ const [count,setCount] = useState(0); function handleClick(){ setCount(count+1); } return( <button onClick={handleClick}> Clicked {count} times </button> ) }useReducer:在reducer函数中声明带有更新逻辑的state变量reducer函数 :将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫做reduceruseReducer钩子接受参数:一个reducer函数一个初始的state返回内容:一个有状态的值一个dispatch函数(派发用户操作给reducer)示例: {tabs}{tabs-pane label="App.js"}import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; import tasksReducer from './tasksReducer.js'; export default funtion TaskApp(){ const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); function handleAddTask(text){ dispatch({ type:'added', id:nextId++, text:text, }); } function handleChangeTask(task){ dispatch({ type:'changed', task:task }); } function handleDeleteTask(taskId){ dispatch({ type:'deleted', id:taskId, }); } return ( <> <h1>布拉格的行程安排</h1> <AddTask onAddTask={handleAddTask} /> <TaskList tasks={tasks} onChangeTask={handleChangeTask} onDeleteTask={handleDeleteTask} /> </> ); }{/tabs-pane}{tabs-pane label="tasksReducer.js"}export default function tasksReducer(tasks, action) { switch (action.type) { case 'added': { return [ ...tasks, { id: action.id, text: action.text, done: false, }, ]; } case 'changed': { return tasks.map((t) => { if (t.id === action.task.id) { return action.task; } else { return t; } }); } case 'deleted': { return tasks.filter((t) => t.id !== action.id); } default: { throw Error('未知 action:' + action.type); } } } {/tabs-pane}{/tabs}Context Hook上下文帮助组件 从祖先组件接收信息,而无需将其作为 props 传递useContext 读取订阅上下文示例:import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); export default function MyApp(){ return ( <ThemeContext.Provider value="dark"> <Form/> <ThemeContext.Provider> ); } function Form(){ return ( <Panel title="Welcome"> <Button>Sign up </Button> <Button>Log in </Button> </Panel> ); } function Panel({title,children}){ const theme = useContext(ThemeContext); const className = 'panel-' + theme; return( <section className = {className}}> <h1>{title}</h1> {children} </section> ); } funciton Button({children}){ const theme = useContext(ThemeContext); const className = 'button-' + theme; return( <button className={className}> {children} </button> ); }注意:通常情况下,useContext()只会调用上层provider,当然通过合并的方式可以实现嵌套调用Ref Hookref 允许组件 保存一些不用于渲染的信息,比如 DOM 节点或 timeout ID。与状态不同,更新 ref 不会重新渲染组件。useRef 声明ref,可以保存任何值,但常用于保存DOM节点示例:import { useRef } from 'react'; export default function Counter() { let ref = useRef(0); function handleClick() { ref.current = ref.current + 1; alert('You clicked ' + ref.current + ' times!'); } return ( <button onClick={handleClick}> 点击!{ref.current} </button> ); } 与useState不同的是,ref不会触发重新渲染,所以JSX中显示{ref.current}不会变化useImperativeHandle 自定义从组件中暴露ref,不常用Effect HookEffect 允许组件 连接到外部系统并与之同步。这包括处理网络、浏览器、DOM、动画、使用不同 UI 库编写的小部件以及其他非 React 代码useEffect 将组件连接到外部系统外部系统 :有些组件需要与网络、某些浏览器 API 或第三方库保持连接,当它们显示在页面上时。这些系统不受 React 控制,所以称为外部系统示例:import {useState,useEffect} from 'react'; import {createConnection} from './chat.js'; function ChatRoom({roomId}){ const [serverUrl,setServerUrl] = useState('https://localhost:1234'); useEffect(()=>{ const connection = createConnection(serverUrl,roomId); connection.connect(); return ()=>{ connection.disconnection(); }; },[serverUrl,roomId]); // ... }需要向 useEffect 传递两个参数:一个 setup 函数 ,其 setup 代码 用来连接到该系统。它应该返回一个 清理函数(cleanup),其 cleanup 代码 用来与该系统断开连接。一个 依赖项列表,包括这些函数使用的每个组件内的值性能 Hook使用性能hook可以跳过计算和不必要的重新渲染来优化性能useMemo 缓存计算代价昂贵的计算结果useMemo(calculateValue, dependencies) calculateValue:要缓存计算值的函数 dependencies:所有在 calculateValue 函数中使用的响应式变量组成的数组示例: {tabs}{tabs-pane label="App.js"}import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; const todos = createTodos(); export default funtion App(){ const [tab,setTab] = useState('all'); const [isDark,setIsDark] = useState(false); return( <> <button onClick={()=>setTab('all')}>All</button> <button onClick={()=>setTab('active')}>Active</button> <button onClick={()=>setTab('completed')}>Completed</button> <br/> <label> <input type="checkbox" checked={isDark} onChange={e=>setIsDark(e.target.checked)}> Dark mode </input> </label> <hr/> <TodoList todos={todos} tab={tab} theme={isDark?'dark':'light'}/> </> ); } {/tabs-pane}{tabs-pane label="TodoList.js"}import { useMemo } from 'react'; import { filterTodos } from './utils.js' export default function TodoList({ todos, theme, tab }) { const visibleTodos = useMemo( () => filterTodos(todos, tab), [todos, tab] ); return ( <div className={theme}> <p><b>Note: <code>filterTodos</code> is artificially slowed down!</b></p> <ul> {visibleTodos.map(todo => ( <li key={todo.id}> {todo.completed ? <s>{todo.text}</s> : todo.text } </li> ))} </ul> </div> ); } {/tabs-pane}{tabs-pane label="utils.js"}export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { todos.push({ id: i, text: "Todo " + (i + 1), completed: Math.random() > 0.5 }); } return todos; } export function filterTodos(todos, tab) { console.log('[ARTIFICIALLY SLOW] Filtering ' + todos.length + ' todos for "' + tab + '" tab.'); let startTime = performance.now(); while (performance.now() - startTime < 500) { // 在 500 毫秒内不执行任何操作以模拟极慢的代码 } return todos.filter(todo => { if (tab === 'all') { return true; } else if (tab === 'active') { return !todo.completed; } else if (tab === 'completed') { return todo.completed; } }); } {/tabs-pane}{/tabs}useCallback 将函数传递给优化组件之前缓存函数定义const cachedFn = useCallback(fn, dependencies) fn:想要缓存的函数 dependencies:有关是否更新 fn 的所有响应式值的一个列表示例:function ProductPage({ productId, referrer, theme }) { // 在多次渲染中缓存函数 const handleSubmit = useCallback((orderDetails) => { post('/product/' + productId + '/buy', { referrer, orderDetails, }); }, [productId, referrer]); // 只要这些依赖没有改变 return ( <div className={theme}> {/* ShippingForm 就会收到同样的 props 并且跳过重新渲染 */} <ShippingForm onSubmit={handleSubmit} /> </div> ); }useMemo与useCallback联系useMemo 经常与 useCallback 一同出现,区别在于useMemo 缓存函数调用的结果 useCallback 缓存函数本身// 在 React 内部的简化实现 function useCallback(fn, dependencies) { return useMemo(() => fn, dependencies); }示例:import { useMemo, useCallback } from 'react'; function ProductPage({ productId, referrer }) { const product = useData('/product/' + productId); const requirements = useMemo(() => { //调用函数并缓存结果 return computeRequirements(product); }, [product]); const handleSubmit = useCallback((orderDetails) => { // 缓存函数本身 post('/product/' + productId + '/buy', { referrer, orderDetails, }); }, [productId, referrer]); return ( <div className={theme}> <ShippingForm requirements={requirements} onSubmit={handleSubmit} /> </div> ); }其他 Hook使用 useDebugValue 自定义 React 开发者工具为自定义 Hook 添加的标签。使用 useId 将唯一的 ID 与组件相关联,其通常与可访问性 API 一起使用。使用 useSyncExternalStore 订阅外部 store。使用 useActionState 允许你管理动作的状态.自定义Hook自定义hook
2025年12月03日
1 阅读
0 评论
0 点赞