react常用hooks案例
react常用hooks及案例
发现很多hooks都没怎么用,想复习一下,后面项目中用起来。 最近开始复习一下react常用的hooks,后面会陆续全部更新完。。。
个人项目中用到的hooks
useState
用于在函数组件中添加"state"状态,以实现在组件中更新和保存状态数据的能力。
写🌰时发现有问题,咦,怎么在div在爆红,然后页面直接白屏了。
原因:
如果你在使用setState时将默认值设置为new Date(),这个日期对象会在组件渲染时被创建。然而,在组件重新渲染时,新创建的日期对象会覆盖掉之前的日期对象,这可能会导致一些不可预测的问题。因此,我们通常不会将日期对象或其他复杂的对象作为初始状态传递给useState。
如果你需要在组件渲染时使用当前日期,可以将日期的字符串表示形式保存。
toLocaleString() 方法可根据本地时间把 Date 对象转换为字符串,并返回结果。
useEffect
用于在函数组件中处理副作用和生命周期方法。useEffect 允许在组件渲染到 DOM 后或在组件被卸载前执行一些操作。
componentDidMount -> useEffect(() => {}, []):组件第一次挂载渲染后执行,通常用于执行订阅、定时器、更新计算等操作。 componentDidUpdate -> useEffect(() => {}):每次渲染后执行,通常用于订阅更新、更新计算等操作。 componentWillUnmount -> useEffect(() => { return () => {} }):组件卸载前执行,通常用于取消定时器、订阅等操作。 useEffect接收一个回调函数作为第一个参数。这个回调函数用来执行一些副作用操作,其中包括调用getList函数,以及设定一个定时器,每10秒钟调用一次getList函数来更新数据。同时,useEffect还接收了一个第二个参数,即一个依赖数组,用来控制useEffect函数的执行。
当search发生改变时,useEffect函数会重新执行,这样就可以保证getList函数会根据新的search进行数据的更新。在组件销毁时,useEffect会返回一个清除函数,这个清除函数则用来清除定时器,以避免内存泄漏。
在上面的代码中,通过调用setInterval函数创建了一个周期性的定时器,并将其返回的定时器ID存储在intervalId变量中。同时,在useEffect的返回函数中,调用了clearInterval函数来清除定时器。
useRef
它返回一个可变的 ref 对象,可以将这个 ref 对象直接绑定到 React 元素上。与传统的 Ref 不同,useRef 返回的 ref 对象在组件重新渲染时不会自动更新,因此可以用来存储一些持久性数据 用法: 1.访问 DOM 元素: 使用 useRef 可以方便地访问 DOM 元素,避免了传统的 DOM 操作方式,例如 document.getElementById() 等。
2.存储变量: useRef 的返回值可以用来存储一些持久性的数据,这些数据与组件的状态无关,也不会触发重新渲染。
3.保存上一次的值: 当需要在组件重新渲染后仍然可以访问上一次的状态时,可以使用 useRef 来保存上一次的值。
useImperativeHandle 用于向外暴露一个组件的某些方法,使得外部可以直接使用这些方法来操作组件内部的状态或行为。这个 hook 将一个 ref 对象作为返回值,与 forwardRef 搭配使用,来实现向父组件暴露子组件的方法。 以往的文章react使用Chart里有完整代码。
useContext
用于在组件中访问某个 Context 的值。Context 是一种用于向组件树中传递数据的方式,它可以向下传递数据给所有的子组件,而不需要手动逐层进行 props 传递。
子组件的ContentContext需要引入父组件定义的,在同一个页面可以这样写。
useCallback
用于在渲染周期之间缓存函数引用,以避免函数在每次渲染时都被重新创建,从而提高组件的性能。
useCallback 用于缓存函数,并保证每次渲染时都返回同一个函数引用。这可以在父组件向子组件传递回调函数时,避免不必要的重新渲染。但是,如果子组件的渲染结果只取决于 props,并且父组件的状态没有改变,则子组件不需要重新渲染。此时,可以使用 React.memo 进一步优化子组件的性能。 React.memo 可以缓存组件的渲染结果,只有当组件的 props 发生变化时,才会重新渲染。如果配合 useCallback 使用,可以确保子组件的回调函数的引用不变,从而进一步保证子组件的缓存效果
点击handleChild1Add打印Child1 点击handleChild2Add打印Child1和Child2 原因: 由于handleChild1Add会直接修改val的值,不会重新生成新的回调函数,所以每次Child1组件渲染时都会打印出console.log('Child1', 1)。 由于handleChild2Add被useCallback包裹,并且其依赖于val1,当val改变时,会重新生成新的缓存版本,而当val1未改变时,其缓存版本会被复用,不会重新生成,所以只有在val1发生改变时,打印才会被触发。因此,只有当Child2组件边上的 val1改变时,才会触发console.log('Child2', 2),而Child1组件因为不存在被useCallback包裹的回调函数,所以每次渲染都会打印。
都加上useCallback就解决了
useMemo
useMemo是React提供的一个钩子函数,用于在函数式组件中进行性能优化。它接收两个参数:一个为回调函数,另一个为依赖数组。在依赖的变量发生变化时,会调用回调函数并返回它的计算结果。如果依赖不变,则直接返回上一次的计算结果。
useReducer
用于在函数式组件中管理本地状态。它可以帮助我们处理复杂的应用程序状态逻辑,并减少代码的冗长和复杂性。
创建初始initialState
创建所有操作reducer(state,action)
传给useReducer,得到读写API
调用写API,参数要包含{type:'操作类型'}
自定义hooks
自定义 Hook 是一种让您可以在函数式组件中重复使用一些状态或逻辑的技术。它通常由一个纯 JavaScript 函数组成,该函数名以 “use” 开头,为函数式组件的各个部分提供了某种状态或逻辑,例如数据获取、状态管理,或动画。
以下是编写自定义 Hook 的一些最佳实践:
以 “use” 开头命名:自定义 Hook 的命名规则应该以 “use” 开头,以便其他开发人员可以识别它们。
避免使用 PropTypes 和默认属性:由于 Hook 不是 React 元素,因此无法使用 PropTypes 来检查导出。也无法使用默认属性和静态属性来确保正确使用。
针对具体任务编写 Hook:自定义 Hook 应该专注于单个功能,并尽量保持简单。尽量将 Hook 设计成通用的,而不是过度定制的解决方案。
以上都是简单案例,记录一下,自己敲出来才会发现有些问题,好记性不如烂笔头,多敲代码吧~ 剩下的其他hooks下次再更新~
转载自:https://juejin.cn/post/7238479969181351997