2024年Web前端最全React入门之ReactHooks基本使用,2024年最新腾讯面试比例

最后

除了简历做到位,面试题也必不可少,整理了些题目,前面有117道汇总的面试到的题目,后面包括了HTML、CSS、JS、ES6、vue、微信小程序、项目类问题、笔试编程类题等专题。


之前我们谈到React的生命周期,里面有三个比较常用的钩子函数,分别是:

  • componentDidMount():会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方
 
  • componentDidUpdate():会在更新后会被立即调用。首次渲染不会执行此方法。
 
  • componentWillUnmount():会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。

在这里插入图片描述

但函数组件没有生命周期,如果想要在页面渲染或更新时执行某些操作,可以使用Hooks的useEffect来完成

下面是一个小例子:

当页面加载或重新渲染(数据更新)时,打印出提示语

引入:

import React, { useState, useEffect } from ‘react’

使用:

// 当页面加载或重新渲染时,打印提示语

useEffect(()=>{

console.log(“useEffect正在执行中。。。”)

})

效果:

当页面刷新时,打印一次;

当添加了书目时,又打印了一次:

在这里插入图片描述

不论是哪个数据更新,都会触发useEffect的执行。如果希望useEffect只追踪某几个变量的变化,可以在useEffect的第二个参数中,传入一个数组;当数组中的变量发生改变时,useEffect就会执行

先来看看多个state时,其中一个state更新,useEffect的反应(同一个组件中可以多次使用useState)

// 另起一个用来存储年龄的state(允许多次使用useState)

const [age, setAge] = useState(22);

// 更新age

const handleClick = ()=>{

setAge(age+1);

}

// 当页面加载或重新渲染时,打印提示语

useEffect(()=>{

console.log(“useEffect正在执行中。。。”,age)

})

创建一个button按钮,点击一下,就修改age:

点击一下年龄+1

效果:

此处我修改了useEffect的输出函数,多加了年龄的打印,这样看得更清楚些。可以看到,无论是修改age还是添加书目,都会触发useEffect

在这里插入图片描述

然后,我们使用useEffect的第二个参数,限定useEffect的使用范围

// 添加第二个参数,当book更新时,才触发打印

useEffect(()=>{

console.log(“useEffect正在执行中。。。”,age)

},[ books ])

效果:一开始页面加载,useEffect会先执行一次;然后我点击增加age,点击两次,都是没有打印输出的(但age有在修改,点击两次,age值为24);最后我添加了书目,才有了打印。可见,限制useEffect的使用范围已生效

在这里插入图片描述

我们还可以在useEffect中将输入的书目进行本地存储

本地存储:localStorage

从文本框输入的书名,网页刷新后就不见了。如果我们存储起来,刷新的时候也能展示新输入的书目

  • 每次数据更新时都存到localStorage:

// 本地存储 BookList.js

useEffect(()=>{

// console.log(“useEffect正在执行中。。。”)

localStorage.setItem(“books”, JSON.stringify(books));

},[ books ])

  • 刷新页面时从localStorage中取出之前的数据,如果第一次加载,就展示初始化的书目即可(也就是《我们仨》《我的阿勒泰》《蒋勋说<红楼梦>》三本书):

// 刷新页面时从localStorage中取出之前的数据

const [books, dispatch] = useReducer(BookReducer, initBooks, ()=>{

const result = localStorage.getItem(‘books’);

return result ? JSON.parse(result) : initBooks

})

效果:

  1. 一开始加载页面,展示初始化的三本书;

  2. 然后我加了一本书名,页面展示4本书名;

  3. 最后我点击左上角的刷新,4本书名还在

在这里插入图片描述

useContext的使用


接着是useContext。

Context-API获取props数据,有两种方法:

  • 一种是通过contextType,只能获取离该组件最近的context,且函数组件不能使用;

  • 另一种是consumer,需要包裹住想要渲染的标签,可以获取多个context。

上一篇文章中,我们嵌套使用多个context时,代码是这样的:

在这里插入图片描述

代码稍微长了一点

如果用useContext,就会简洁很多

import React, { Component,useContext } from ‘react’

import { ThemeContext } from ‘…/contexts/ThemeContext’;

import { GreetingContext } from ‘…/contexts/GreetingContext’;

const Navbar = ()=>{

const greetingContext = useContext(GreetingContext); // GreetingContext使用

const themeContext = useContext(ThemeContext); // ThemeContext使用

const { isAGirl, toggleGreeting } = greetingContext;

const { isLightTheme, light, dark } = themeContext;

const theme = isLightTheme ? light : dark;

return (

Context App

{ isAGirl ? ‘hello,girl~’ : ‘hello,boy~’}

    • Home
    • About
    • Contact
    • )

      }

      export default Navbar;

      useReducer的使用


      我们知道,除了context,还有一种方法可以统一管理数据,那就是redux。redux提供了一个store来管理数据,而数据的更新,是交由reducer来执行的,ReactHooks也提供了这样的方法——useReducer,可以统一管理数据,增强代码的可维护性和可读性

      在useState的例子中,我们把数据的存储、数据的修改方法都写在了使用数据的组件里,这个组件既要管理数据,又要展示数据。我们可以使用useContext来抽离数据,用useReducer抽离数据的更新操作,不论哪个子组件,都能调用dispatch派发action行为,就像这样:

      BookReducer.js文件中设置action

      import React from ‘react’

      import {v4 as uuidv4} from ‘uuid’

      const BookReducer = (state, action)=>{

      switch (action.Type){

      case “ADD_BOOK”:{

      return […state,{title:action.book.title, id:uuidv4()}]

      }

      }

      }

      export default BookReducer;

      BookList.js文件中接收,并把dispatch传递给子组件AddBook去使用

      import React, { useState, useEffect,useContext,useReducer } from ‘react’

      import AddBook from ‘./AddBook’

      import {v4 as uuidv4} from ‘uuid’

      import { BookContext } from ‘…/context/BookContext’

      const BookList = () => {

      const {books, dispatch} = useContext(BookContext);

      // 当页面加载或重新渲染时,打印提示语

      useEffect(()=>{

      console.log(“useEffect正在执行中。。。”)

      },[ books ])

      return (

      {/* 展示数据:书目 */}

        {books.map(book => {

        return (

      • {book.title}
      • )

        })}

        {/* 将更新书目的方法传递给子组件,让子组件执行 */}

        {/* */}

        打开全栈工匠技能包-1小时轻松掌握SSR

        两小时精通jq+bs插件开发

        生产环境下如歌部署Node.js

        开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

        网易内部VUE自定义插件库NPM集成

        谁说前端不用懂安全,XSS跨站脚本的危害

        webpack的loader到底是什么样的?两小时带你写一个自己loader

      • 29
        点赞
      • 25
        收藏
        觉得还不错? 一键收藏
      • 0
        评论
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值