返回顶部
首页 > 资讯 > 前端开发 > VUE >如何学习React-Hook
  • 899
分享到

如何学习React-Hook

2024-04-02 19:04:59 899人浏览 独家记忆
摘要

本篇内容主要讲解“如何学习React-Hook”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何学习React-Hook”吧!数据绑定在react中state的

本篇内容主要讲解“如何学习React-Hook”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何学习React-Hook”吧!

数据绑定

在react中state的概念是内部状态的管理,它的变更直接会影响页面的渲染。

在hook中把setState拆开了。每一个单个的state的都会是一个单个的状态,单个状态的变更不会影响其他state。我们可以通过useState实现单个状态的初始化定义。

useState的参数可以是一个数字、字符串、布尔值、数组或对象,也可以是一个函数。

同样我们避免不了会使用集合(对象)来处理一些逻辑。

const [count, setCount] = useState(0); const [count, setCount] = useState(() => 0); const [obj, setObj] = useState({}); setObj((prevObj) => {   // 也可以使用 Object.assign   return { ...prevObj, age: 23 }; });

一般我们会定义一个初始值initialState,如果这个初始值,需要额外的计算开销,我们可以定义一个函数来处理。需要注意的是,useState  函数只会在初始渲染的时候被调用。

const [state, setState] = useState(() => {   // 额外的操作someExpensiveComputation   const initialState = someExpensiveComputation(props);   return initialState; });

对于多个state集合的处理,还有另一种方案就是useReducer。

  • 比如单个 state 的状态会影响多个 state 的值的时候。

  • 比如多个 state 的状态会随着某种类型的改变而改变。

如下多个 state 会随着登录、登出、刷新 token 这三种状态的改变而改变。

const [state, dispatch] = React.useReducer(   (prevState, action) => {     switch (action.type) {       case "RESTORE_TOKEN":         return {           ...prevState,           userToken: action.token,           isLoading: false,         };       case "SIGN_IN":         return {           ...prevState,           isSignout: false,           userToken: action.token,         };       case "SIGN_OUT":         return {           ...prevState,           isSignout: true,           userToken: null,         };     }   },   {     isLoading: true,     isSignout: false,     userToken: null,   } );

副作用

hook 提供了一种新的概念来代替生命周期函数,就是useEffect副作用。它被看作是从 React 的纯函数式世界通往命令式世界的逃生通道。

它的执行时机是在屏幕元素渲染结束后延迟执行。

它的作用有:

  • 它可以监控 state 值的变化

  • 它可以处理只运行一次的逻辑,有点类似生命周期 componentDidMount 和 componentWillUnmount 的思维模式,

  • 添加订阅、设置定时器、发送网络请求

  • 更多其他

// 通过的第二个参数来实现只执行一次或监控state值 useEffect(() => {   // ... }, []);  // useEffect第一个参数的返回函数就是componentWillUnmount的思想,在组件卸载之前进行 useEffect(() => {   const subscription = props.source.subscribe();   return () => {     // 清除订阅     subscription.unsubscribe();   }; });

但是这种延迟执行的机制不能满足我们所有的场景,如果我们想要实现屏幕绘制和副作用同步执行,比如实时修改dom结构等这样的场景,useEffect无法满足,会出现闪屏的效果。

我们可以通过useLayoutEffect来实现,它的执行时机是在组件加载完成后,屏幕绘制之前进行。但这样也有缺点就是阻塞屏幕渲染,可能会出现白屏或停顿。

所以useLayoutEffect的使用场景:

  • 防止闪烁,比较耗时的计算

  • Dom操作

  • componentDidMount和componentDidUpdate的场景

如果只是单独的获取(get操作)就没有必要使用useLayoutEffect。

组件传值

组件传值的核心:

  • 父传子,通过在子组件设置属性;

  • 子传父,通过回调。

  • 多级组件,通过中间状态管理

// 父组件 function Home() {   const [currentTab, setCurrentTab] = useState("msg");   return (     <>       <View style={styles.loGo}>          // 父传子         <TabView currentTab={currentTab} setCurrentTab={setCurrentTab} />         // 子传父         <CodeView code={code} changeCode={(code)=>setCurrentTab(code)} />       </View>       <Text>{currentTab}</Text>     </>   ); }  //子组件 function TabView({ currentTab, setCurrentTab }) {   return (     <View style={styles.logo}>       <Text>{currentTab}</Text>       <Button         title="修改tab"         onPress={() => {           setCurrentTab("pass");         }}       />     </View>   ); } //子传父 function CodeView({ code, changeCode }) {   return (     <View style={styles.logo}>       <Text>{code}</Text>       <Button         title="修改tab"         onPress={changeCode}       />     </View>   ); }

多组件的传值,可以通过context来处理。

export const MyContent = React.createContext({});  function Home() {   return (     <MyContent.Provider       value={{         currentTab,         phoneValue,         codeValue,         setPhoneValue,         setCodeValue,       }}     >       <FORMItem />       <SwitchItemView />     </MyContent.Provider>   ); }  function FormItem() {   const { phoneValue, setPhoneValue } = useContext(MyContent);   return (     <View style={styles.logo}>       <Text>{phoneValue}</Text>       {}     </View>   ); }  function SwitchItemView() {   const { codeValue, setCodeValue } = useContext(MyContent);   return (     <View style={styles.logo}>       <Text>{phoneValue}</Text>       {}     </View>   ); }

元素节点操作

hook通过useRef来创建节点对象,然后通过ref挂载,通过current来获取。

function TextInputWithFocusButton() {   const inputEl = useRef(null);   const onButtonClick = () => {     inputEl.current.focus();   };   return (     <>       <input ref={inputEl} type="text" />       <button onClick={onButtonClick}>Focus the input</button>     </>   ); }

我们可能会封装一些逻辑,自定义一些属性,暴露给父元素,那么我们就会用到useImperativeHandle和forwardRef。

function FancyInput(props, pref) {   const inputRef = useRef();   useImperativeHandle(ref, () => ({     focus: () => {       inputRef.current.focus();     }   }));   return <input ref={inputRef} ... />; }  FancyInput = forwardRef(FancyInput);  <FancyInput ref={inputRef} />  // 父组件可以直接调用inputRef.current.focus()

因为 ref 对象不会把当前 ref 值的变化通知给我们,所以我们必须通过useState和useCallback实现。

function MeasureExample() {   const [height, setHeight] = useState(0);    const measuredRef = useCallback((node) => {     if (node !== null) {       setHeight(node.getBoundinGClientRect().height);     }   }, []);    return (     <>       <h2 ref={measuredRef}>Hello, world</h2>       <h3>The above header is {Math.round(height)}px tall</h3>     </>   ); }

自定义hook

在代码中,我们会有一些共用的逻辑,我们可以抽离出来比如自定义的防抖节流,自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的  Hook。

const useDebounce = (fn, ms = 30, deps = []) => {   let timeout = useRef();    useEffect(() => {     if (timeout.current) clearTimeout(timeout.current);     timeout.current = setTimeout(() => {       fn();     }, ms);   }, deps);    const cancel = () => {     clearTimeout(timeout.current);     timeout = null;   };   return [cancel]; };  export default useDebounce; const Home = (props) => {   const [a, setA] = useState(0);   const [b, setB] = useState(0);   const [cancel] = useDebounce(     () => {       setB(a);     },     2000,     [a]   );    const changeIpt = (e) => {     setA(e.target.value);   };    return (     <div>       <input type="text" onChange={changeIpt} />       {b} {a}     </div>   ); };

性能优化

单向数据流,各组件层次分明,状态明确,但是当项目体量大,组件嵌套多的时候,性能损耗也非常大,所以我们会做一些性能优化的工作。

可能的优化场景有:

  • 单个 state  的更新会影响全局,有一点需要注意的是,被context包裹的组件,只要value的任何一个变动,都会重新渲染,useMemo和useCallback就会失效。

  • 相同的输入,不再重新计算

  • 父组件的函数在子组件使用的时候

其实useMemo和useCallback的核心思想相同,都是记录上一次的输入,如果下一次输入与上一次相同,将不会计算,直接获取上一次的结果。他们的区别只是形式上的,useMemo返回一个  memoized 值。而useCallback返回的是memoized回调函数。

useMemo缓存计算结果的值。

useCallback主要用于缓存函数。

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。

const memoizedCallback = useCallback(() => {   doSomething(a, b); }, [a, b]);  // useMemo const [count, setCount] = useState(1); const [val, setValue] = useState(""); const expensive = useMemo(() => {   let sum = 0;   for (let i = 0; i < count * 100; i++) {     sum += i;   }   return sum; }, [count]);  return (   <div>     <h5>       {count}-{expensive}     </h5>     {val}     <div>       <button onClick={() => setCount(count + 1)}>+c1</button>       <input value={val} onChange={(event) => setValue(event.target.value)} />     </div>   </div> );

捎带了解一下memoized,简单讲就是把函数的计算结果缓存起来,比如递归

const memoize = function(fn) {     const cache = {};     return function() {         const key = JSON.stringify(arguments);         var value = cache[key];         if(!value) {             console.log('新值,执行中...');         // 为了了解过程加入的log,正式场合应该去掉             value = [fn.apply(this, arguments)];  // 放在一个数组中,方便应对undefined,null等异常情况             cache[key] = value;         } else {             console.log('来自缓存');               // 为了了解过程加入的log,正式场合应该去掉         }         return value[0];     } }  module.exports = memoize; const memoize = require('./memoize.js'); const log = console.log;  // 斐波那契数组 const fibonacci = (n) => {     return n < 2          ? n         : fibonacci(n - 1) + fibonacci(n - 2); };  const memoizeFibonacci = memoize(fibonacci);  log(memoizeFibonacci(45));   // 新值,执行中...;    1134903170  // 等待时间比较长 log(memoizeFibonacci(45));   // 来自缓存;    1134903170 log(memoizeFibonacci(45));   // 来自缓存;    1134903170 log(memoizeFibonacci(45));   // 来自缓存;    1134903170

到此,相信大家对“如何学习React-Hook”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 如何学习React-Hook

本文链接: https://lsjlt.com/news/83784.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何学习React-Hook
    本篇内容主要讲解“如何学习React-Hook”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何学习React-Hook”吧!数据绑定在react中state的...
    99+
    2024-04-02
  • React Hook中如何使用State Hook
    今天小编给大家分享一下React Hook中如何使用State Hook的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起...
    99+
    2023-06-29
  • React如何自定义hook
    本篇内容主要讲解“React如何自定义hook”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“React如何自定义hook”吧!什么是hookHook是 React 16.8 的新增特性。它通常与...
    99+
    2023-07-02
  • hook如何在react中使用
    今天就跟大家聊聊有关hook如何在react中使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、什么是hook?react hook是react 16.8推出的方法,能够让函数式...
    99+
    2023-06-14
  • python学习之路--hook(钩子原
    ** 什么是钩子 ** 之前有转一篇关于回调函数的文章http://blog.csdn.net/Mybigkid/article/details/67644490 钩子函数、注册函数、回调函数,...
    99+
    2023-01-31
    钩子 之路 python
  • React Hook中useEffecfa函数如何使用
    这篇文章主要介绍“React Hook中useEffecfa函数如何使用”,在日常操作中,相信很多人在React Hook中useEffecfa函数如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Rea...
    99+
    2023-07-04
  • 从零开始学习React
    这篇文章主要讲解了“从零开始学习React”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“从零开始学习React”吧!0: 从一次最简单的 React 渲染说...
    99+
    2024-04-02
  • 怎么学习React Hooks原理
    这篇文章主要介绍“怎么学习React Hooks原理”,在日常操作中,相信很多人在怎么学习React Hooks原理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么学习Re...
    99+
    2024-04-02
  • React系列useSyncExternalStore学习详解
    目录前言useSyncExternalStore 初体验Concurrent 模式下使用 react-redux 7Concurrent 模式下使用 react-redux 8Con...
    99+
    2024-04-02
  • react学习每天一个hooks useWhyDidYouUpdate
    目录先讲点废话来看看效果hooks源码来了demo完整源码先讲点废话 这个hooks我记忆很深,因为当时有一次面试的时候,叫我手写实现这个自定义hooks,哈哈,所以这个系列的第一个...
    99+
    2023-05-18
    react hooks useWhyDidYouUpdate react hooks
  • React脚手架搭建的学习
    一、前端工程的复杂化 如果我们只是开发几个小的demo程序,那么永远不需要考虑一些复杂的问题: 比如目录结构如何组织划分;比如如何管理文件之间的相互依赖;比如如何管理第三方模块的依...
    99+
    2024-04-02
  • React组件学习之Hooks使用
    目录一、前言二、React Hooks2.1 useState2.2 useEffect2.3 useMemo2.4 useCallback2.5 useContext2.6 use...
    99+
    2024-04-02
  • 如何通过实例学习React中事件节流防抖
    这篇文章将为大家详细讲解有关如何通过实例学习React中事件节流防抖,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。节流方法一import Throttle&nb...
    99+
    2024-04-02
  • 如何学习php
    学习php的方法需要了解PHP、html、css、js有什么用。先学习html,css,js。多动手把html,css,js熟练后开始学习php。以“php把数据库的资源和页面做交互”为中心去学习。自己动手开发简单案例,深入理解MVC,面向...
    99+
    2024-04-02
  • 如何学习composer
    小编给大家分享一下如何学习composer,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!听说你也想学composer-入门篇composer作为依赖管理工具,使用频率还是挺高的。特别是对于我这种比较懒的程序猿,有现成轮子的...
    99+
    2023-06-14
  • 如何学习WCF
    这篇文章给大家分享的是有关如何学习WCF的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。对于WCF学习,技术态度要扎实。如果你是新手,有足够的时间,建议你从基础学起,现了解Enterprise Sevices(CO...
    99+
    2023-06-17
  • 如何学习html
    随着互联网的发展,HTML(超文本标记语言)作为Web开发的核心技术逐渐被广泛认知和应用。许多人想学习HTML,但不知道从何开始,如何学习,此时这篇文章将为您详细介绍一些学习HTML的方法和技巧。1、初步学习HTML学习HTML需要有基本的...
    99+
    2023-05-14
  • 如何学习 HTML
    HTML(超文本标记语言)是构建万维网(World Wide Web)页面的一种基础技术,学习 HTML 的好处包括能够创建自己的网页,了解网页开发的基本原则以及更好地理解网页之间的关系等。那么,如何学习 HTML 代码呢?本文将从以下几个...
    99+
    2023-05-14
  • python如何学习
    python如何来学习别人口中python应该怎么学习:1、python不是拿来学的,而是拿来用的。    python的语法结构很简单,或者说书本里面的东西很容易掌握。但是你要把python真正的用好,是有很大难度的。而且从这句话可以看出...
    99+
    2023-01-31
    python
  • 如何学习selenium
    这篇文章主要为大家展示了“如何学习selenium”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何学习selenium”这篇文章吧。要弄懂什么是Selenium?Selenium是浏览器自动化...
    99+
    2023-06-05
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作