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

成都网站建设哪家长沙网站seo方法

成都网站建设哪家,长沙网站seo方法,网站以什么名字备案,做游戏门户网站要注意什么为什么hook必须在组件内的顶层声明? 这是为了确保每次组件渲染时,Hooks 的调用顺序保持一致。React利用 hook 的调用顺序来跟踪各个 hook 的状态。每当一个函数组件被渲染时,所有的 hook 调用都是按照从上到下的顺序依次执行的。React 内部会…

为什么hook必须在组件内的顶层声明?

这是为了确保每次组件渲染时,Hooks 的调用顺序保持一致。React利用 hook 的调用顺序来跟踪各个 hook 的状态。每当一个函数组件被渲染时,所有的 hook 调用都是按照从上到下的顺序依次执行的。React 内部会维护一个状态列表,这个列表中的每个状态项都对应一个 hook 的调用,包括 useState、useEffect 等。当你调用 useState(initialValue) 时,React 会在内部为这个状态分配一个索引。该索引基于 hook 调用的顺序。例如,第一次调用 useState 时,它会在状态列表的第一个位置存储状态,第二次调用会在第二个位置存储,以此类推

考虑下面这个demo:

const Component = () => {const [count, setCount] = useState(0);const handleOfClick = () => setCount(count + 1);return <button onClick={setCount}>{count}</button>
}

Q:既然每次视图的更新都会重新执行整个函数,那必然会执行到const [count, setCount] = useState(0)这句代码。如果我在上一次更新中把count加到10,为什么在新的渲染周期中,React能记住这个10而不是传给useState的0呢?
A:当组件重新渲染时,React 会根据组件的调用顺序再次按顺序调用对应的 hook。这样,React 可以确保它能够始终访问到正确的状态。例如,当第二次渲染时,React 知道第一个 useState 是哪个状态,因为它在第一次渲染时已经分配了这个状态的索引,这个索引是靠hook调用的顺序产生的索引来追踪的。 所以如果在条件语句、循环或嵌套函数中调用 hook,可能会导致调用顺序的变化,从而产生不可预知的状态。


useImperativeHandle

useImperativeHandle通常是和forwardRef配合使用的,用来把子组件中的属性或者方法暴露给父组件,在进行组件的封装或者组件间的通信的时候常会使用。如下:

// 封装一个可拖拽的组件
const DragComponent = forwardRef((props: {children: React.ReactNode, // 求求你不要挂一个很复杂的组件进来🙏// other config...},ref // ref是必须的) => {// 复位const resetPosition = () => {// todo: 可以在父组件中调用,让这个可拖拽的组件在父组件中回到第一次渲染的位置}useImperativeHandle(ref, () => {resetPosition // 显式声明})return (<div>{props.children}</div>)}
)// 之后在某一个页面中使用它
const Page = () => {const dragRef = useRef(null)const handleOfClick = () => {dragRef.current?.reset();}return (<div><DragComponent ref={dragRef}/><button onClick={handleOfClick}>复位</button></div>)
}

useCallback

useCallBack用来缓存一个函数的引用,它常常配合memo使用以提高渲染的性能。

const Component = memo(({ count, setCount }: { count: number; setCount: () => void }
) => {console.log("CountComponeng render");return (<div><button onClick={() => setCount()}>CountComponeng: {count}</button></div>);})function App() {console.log("App render");const [parentCount, setParentCount] = useState(0);const [childCount, setChildCount] = useState(0);const addChildCount = useCallback(() => {setChildCount(childCount + 1);}, [childCount]);// 这样也行// const addChildCount = useCallback(() => {//     setChildCount((count) => count + 1);// }, []);return (<div id="app"><h1>Hello Vite + React!</h1><button onClick={() => setParentCount(parentCount + 1)}>parentCount: {parentCount}</button><CountComponeng setCount={setChildCount} count={childCount} /></div>);
}export default App;

useReducer

类似redux的更规范的写法,我用的还不多😢,权当记录(该说不说,确实优雅):

import React, { useReducer } from "react";// 定义初始状态
const initialState = { count: 0 };// 定义 reducer 函数
const reducer = (state, action) => {switch (action.type) {case "increment":return { count: state.count + 1 };case "decrement":return { count: state.count - 1 };default:return state;}
};const Counter = () => {// 使用 useReducerconst [state, dispatch] = useReducer(reducer, initialState);return (<div><p>Count: {state.count}</p><button onClick={() => dispatch({ type: "increment" })}>Increment</button><button onClick={() => dispatch({ type: "decrement" })}>Decrement</button></div>);
};
export default Counter;

setState的函数写法和变量写法

我有这样的代码:const [count, setCount] = useState(0),在普通的情况下setCount(count + 1)setCount((count) => count + 1)都能实现count加1并更新视图的操作。

但是,考虑下面这个demo:

const handleOfClick = () => {setCount(count+1)setCount(count+1)setCount(count+1)
}

每一次点击,count最终都只能加1而不能加3,这个React官网介绍的很清楚这里不多说。但是如果把上面的setCount(count+1)换成setCount((count) => count + 1),确实能实现点击一次就+3并更新视图的功能,因为这种函数的写法保证了在进行状态更新时,能够获取到最新的状态值,特别是在状态更新依赖于之前的状态值时,可以避免因为异步执行导致的潜在问题。
始终记住setState是异步的,而且不是没setState一次就更新一次视图的(涉及到React为了优化渲染性能而使用的批量更新策略)。

再考虑一个更普遍的场景:

const Page = () => {const [count, setCount] = useState(1);useEffect(() => {const scrollableContainer = document.getElementById("scrollable-container");scrollableContainer?.addEventListener("scroll", () => {setCount(count + 1)});}, [])return <div id="scroll-container">{count}</div>
}

你会发现,任凭你滚动的再快,count只会加到2,然后就一直不变了。因为此处的useEffect只会执行一次,当你使用 addEventListener 直接绑定事件时,你得到的是一个闭包。在这个闭包中,count 的值是在事件绑定时捕获的(1)
但是把setCount(count+1)换成setCount((count) => count + 1)就能每次滚动的时候都加1,因为它会接受当前状态作为参数,这样每次更新都会基于最新的状态进行计算,从而避免因为闭包问题导致的状态不正确的问题。

http://www.hkea.cn/news/697651/

相关文章:

  • 台州专业网站建设方案seo软文代写
  • 个人网站 百度推广全球搜索大全
  • 网站消息推送5118素材网站
  • 天津 响应式网站设计企业网站模板免费
  • 网站用花生壳nas做存储百度seo发包工具
  • wordpress cache深圳纯手工seo
  • 怎样找到正规代加工网站百度地图3d实景地图
  • 潍坊网站建设公司网站搭建免费
  • 惠州做网站好的公司下载百度语音导航地图安装
  • 春节网站怎么做小说排行榜百度搜索风云榜
  • 商城服务是什么软件seo是指什么岗位
  • 无锡网站建设有限公司网站快速收录的方法
  • 网站建设通报推广网站多少钱
  • 网络推广公司成都seo排名优化教程
  • 一台手机登录微信网页版西安优化外
  • 如何做旅游攻略网站长沙seo优化推荐
  • 长春火车站电话咨询电话快排seo
  • 龙城建设网站公司网站内容优化方法
  • 南通网站建设搭建网站卖链接
  • 驻马店市做网站seo臻系统
  • 找公司做网站怎么图片都要自己找百度推广官网电话
  • 网站小样用什么做seo外链平台热狗
  • 建站点的步骤sem是什么
  • 深圳专业做网站的衡水网站优化推广
  • 徐汇科技网站建设2345中国最好的网址站
  • 邢台论坛吧百度seo收录软件
  • 做国外服务器网站吗怎么让百度搜索靠前
  • 做动态图网站有哪些自建站怎么推广
  • web网站开发课程设计报告seo技术培训沈阳
  • 会宁网站建设公司网站优化助手