13人参与 • 2025-02-14 • Javascript
usecallback 是 react 的一个 hook,用于记忆函数定义,避免在每次渲染时创建新的函数实例。它在需要将回调函数传递给经过优化的子组件时特别有用。 当state变化的时候引起组件重新渲染执行会导致某个方法被反复创建增加内存负担,这个时候可以使用usecallback将该函数进行缓存,只创建一次
const memoizedcallback = usecallback( () => { dosomething(a, b); }, [a, b], // 依赖项数组 );
同样的当依赖项省略时组件重新渲染都会执行,当依赖项为空数组的时候只有组件初始化的时候会执行一次,数组里有依赖项的时候依赖项发生变化的时候都会缓存一次
function parentcomponent() { const [count, setcount] = usestate(0); // ❌ 每次渲染都会创建新的函数实例 const handleclick = () => { console.log('clicked'); }; // ✅ 函数实例会被记忆,只在依赖项变化时更新 const handleclickmemoized = usecallback(() => { console.log('clicked'); }, []); // 空依赖数组,函数永远不会改变 return <childcomponent onclick={handleclickmemoized} />; }
// 子组件使用 react.memo 优化 const childcomponent = react.memo(function childcomponent({ onclick }) { console.log("childcomponent rendered"); return <button onclick={onclick}>click me</button>; }); // 父组件使用 usecallback function parentcomponent() { const [count, setcount] = usestate(0); const [text, settext] = usestate(""); // 使用 usecallback 记忆回调函数 const handleclick = usecallback(() => { setcount(c => c + 1); }, []); // 空依赖数组,因为不依赖任何值 return ( <div> <input value={text} onchange={e => settext(e.target.value)} /> <p>count: {count}</p> <childcomponent onclick={handleclick} /> </div> ); }
function searchcomponent({ onsearch }) { const [searchterm, setsearchterm] = usestate(""); const [searchhistory, setsearchhistory] = usestate([]); // 使用 usecallback 记忆搜索函数 const handlesearch = usecallback(() => { if (searchterm.trim()) { onsearch(searchterm); setsearchhistory(prev => [...prev, searchterm]); } }, [searchterm, onsearch]); // 依赖 searchterm 和 onsearch return ( <div> <input value={searchterm} onchange={e => setsearchterm(e.target.value)} /> <searchbutton onclick={handlesearch} /> <searchhistory items={searchhistory} /> </div> ); } // 优化的子组件 const searchbutton = react.memo(function searchbutton({ onclick }) { console.log("searchbutton rendered"); return <button onclick={onclick}>搜索</button>; }); const searchhistory = react.memo(function searchhistory({ items }) { return ( <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); });
function complexform() { const [formdata, setformdata] = usestate({ name: '', email: '', message: '' }); // 记忆表单字段更新函数 const handlefieldchange = usecallback((fieldname) => (event) => { setformdata(prev => ({ ...prev, [fieldname]: event.target.value })); }, []); // 不需要依赖项,因为使用了函数式更新 return ( <form> <formfield label="name" value={formdata.name} onchange={handlefieldchange('name')} /> <formfield label="email" value={formdata.email} onchange={handlefieldchange('email')} /> <formfield label="message" value={formdata.message} onchange={handlefieldchange('message')} /> </form> ); } const formfield = react.memo(function formfield({ label, value, onchange }) { console.log(`${label} field rendered`); return ( <div> <label>{label}</label> <input value={value} onchange={onchange} /> </div> ); });
function todolist() { const [todos, settodos] = usestate([]); // 记忆添加任务函数 const handleadd = usecallback((text) => { settodos(prev => [...prev, { id: date.now(), text, completed: false }]); }, []); // 记忆切换完成状态函数 const handletoggle = usecallback((id) => { settodos(prev => prev.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo ) ); }, []); // 记忆删除函数 const handledelete = usecallback((id) => { settodos(prev => prev.filter(todo => todo.id !== id)); }, []); return ( <div> <addtodo onadd={handleadd} /> {todos.map(todo => ( <todoitem key={todo.id} todo={todo} ontoggle={handletoggle} ondelete={handledelete} /> ))} </div> ); } const todoitem = react.memo(function todoitem({ todo, ontoggle, ondelete }) { return ( <div> <input type="checkbox" checked={todo.completed} onchange={() => ontoggle(todo.id)} /> <span style={{ textdecoration: todo.completed ? 'line-through' : 'none' }}> {todo.text} </span> <button onclick={() => ondelete(todo.id)}>删除</button> </div> ); });
function userprofile({ userid, onupdate }) { // ✅ 只在 userid 或 onupdate 变化时更新 const handleupdate = usecallback(() => { onupdate(userid); }, [userid, onupdate]); // ❌ 不必要的依赖项 const handleclick = usecallback(() => { console.log('clicked'); }, [userid]); // userid 不需要作为依赖项 }
// ❌ 简单组件不需要使用 usecallback function simplebutton({ onclick }) { return <button onclick={onclick}>click me</button>; } // ✅ 复杂组件或频繁重渲染的组件使用 usecallback const complexcomponent = react.memo(function complexcomponent({ onaction }) { // 复杂的渲染逻辑 return ( // ... ); });
function datafetcher({ query }) { const [data, setdata] = usestate(null); // 记忆获取数据的函数 const fetchdata = usecallback(async () => { const response = await fetch(`/api/search?q=${query}`); const result = await response.json(); setdata(result); }, [query]); // 在 effect 中使用记忆的函数 useeffect(() => { fetchdata(); }, [fetchdata]); // fetchdata 作为依赖项 return <div>{/* 渲染数据 */}</div>; }
function dataprocessor({ data, onprocess }) { // 记忆处理函数 const processdata = usecallback((item) => { // 复杂的数据处理逻辑 return someexpensiveoperation(item); }, []); // 使用记忆的函数处理数据 const processeddata = usememo(() => { return data.map(processdata); }, [data, processdata]); return ( <div> {processeddata.map(item => ( <processeditem key={item.id} item={item} onprocess={onprocess} /> ))} </div> ); }
避免过度使用
正确设置依赖项
配合 react.memo 使用
考虑使用场景
通过合理使用 usecallback 和 react.memo,我们可以有效优化 react 应用的性能。但要记住,过度优化可能会适得其反,应该在实际需要时才进行优化。
到此这篇关于react usecallback使用方法详解的文章就介绍到这了,更多相关react usecallback内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论