React:Hook
发布日期:2021-06-30 15:49:27 浏览次数:3 分类:技术文章

本文共 11244 字,大约阅读时间需要 37 分钟。

一、为什么要用React Hook

1. 官方介绍

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

2. 组件类的几个缺点

  1. 大型组件很难拆分和重构,也很难测试
    ① 业务变得复杂之后,组件之间共享状态变得频繁,此时组件将变得非常难以理解和维护,复用状态逻辑更是难上加难
    ② 如果使用redux和其中间件, 又将极大的加大项目的复杂度和体积 , 而且需要按照一套严格的标准去写组件和redux,才能保证一定的可维护和可扩展性
  2. 业务逻辑分散在组件的各个方法之中,导致重复逻辑或关联逻辑
  3. 组件类引入了复杂的编程模式,比如 render props 和高阶组件

3. 解决方案

  1. 提出思路
    React 团队希望,组件不要变成复杂的容器,最好只是数据流的管道
    ① 开发者根据需要,组合管道即可
    ② 组件的最佳写法应该是函数,而不是类
    React 早期版本也支持函数组件
    ① 但是,这种写法有重大限制,必须是纯函数,不能包含状态
    ② 也不支持生命周期方法,因此无法取代类
  2. React Hooks 诞生:React Hook 就是加强版函数组件,完全不使用"类",就能写出一个全功能的组件

二、什么是React Hook

1. 什么是React Hook

  1. Hook

    钩子

  2. React Hooks 含义

    ① 组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来
    ② React Hooks 就是那些钩子

  3. 使用React Hook

    ① 概念

    1. React 默认提供了一些常用钩子
    2. 我们也可以封装自己的钩子
    3. 所有的钩子都是为函数引入外部功能,所以 React 约定,钩子一律使用use前缀命名,便于识别
    4. 你要使用 xxx 功能,钩子就命名为 usexxx

    ② 常用钩子

    1. useState()
    2. useContext()
    3. useReducer()
    4. useEffect()
  4. 案例实操

    ① useState基本使用

    // 1. 常规写法// import React from 'react'//// export default class Like001 extends React.Component {
    // state = {
    // age: 0// }//// render() {
    // return (//
    //

    我今年{this.state.age}岁了!

    //
    //
    // );// }// }// 2. hook使用 ——> useStateimport React, {
    useState} from 'react'export default () => {
    // 2.1 使用钩子 const [age, setAge] = useState(0); const name = useState('KaiSarH') return (

    老子是{
    name}

    我今年{
    age}岁了!

    )}

    ② useEffect基本使用

    // 1. 常规写法// import React from 'react'//// export default class Like001 extends React.Component {
    // state = {
    // count: 0// }//// componentDidMount() {
    // document.title = `点击了${this.state.count}次!`// }//// componentDidUpdate(prevProps, prevState, snapshot) {
    // document.title = `点击了${this.state.count}次!`// }//// render() {
    // return (//
    //

    点击了{this.state.count}次!

    //
    //
    // );// }// }// 2. hook使用 ——> useState、useEffectimport React, {
    useState, useEffect} from 'react'export default () => {
    const [count, setCount] = useState(0); // useEffect——componentDidMount componentDidUpdate componentWillUnmount useEffect(() => {
    document.title = `点击了${
    count}次` }); return (

    点击了{
    count}次!

    )}

    ③ todo简单案例

    useEffect第二个参数运用

    1. []相当于生命周期函数的:componentDidMount
    2. 有第二个参数:相对于生命周期函数:componentDidMount componentDidUpdate
    3. [count]:只监听count发生改变的时候,才会触发 componentDidUpdate
      // // 1. 常规写法// import React from 'react'//// export default class Like003 extends React.Component {
      // state = {
      // count: 0,// name: 'KaiSarH'// }//// componentDidMount() {
      // document.title = `点击了${this.state.count}次!`// }//// componentDidUpdate(prevProps, prevState, snapshot) {
      // // document.title = `点击了${this.state.count}次!`// if (prevProps.count !== this.state.count) {
      // document.title = `点击了${this.state.count}次!`// }// }////// _dealCountClick() {
      // this.setState({
      // count: this.state.count + 1// })// }//// _dealNameClick() {
      // // let name = this.state.name === 'King James' ? 'KaiSarH' : 'King James';// this.setState({
      // name: 'King James'// })// }//// render() {
      // return (//
      //

      点击了{this.state.count}次!

      //

      {this.state.name}

      //
      //
      //
      // );// }// }// 2. hook使用 ——> useState、useEffectimport React, {
      useEffect, useState} from 'react'export default () => {
      const [count, setCount] = useState(0); const [name, setName] = useState('KaiSarH'); /* * 1. 如果不加第二个参数,默认是执行:componentDidMount componentDidUpdate * 2. 加了中括号,默认执行componentDidMount * 3. [状态]:只有状态发生改变时,才能触发componentDidUpdate * */ useEffect(() => {
      console.log('执行了·······') document.title = `点击了${
      count}次` // return 中返回的相当于在componentWillUnMount return {
      } }, [count]) return (

      姓名:{
      name}

      次数:{
      count}

      )}
    4. return:相当于componentWillUnmount
      // 1. 常规写法import React, {
      useState, useEffect} from 'react'import ReactDOM from 'react-dom'const AgeAPI = {
      age: 0, subscribe(callBack) {
      this.intervalId = setInterval(() => {
      console.log('定时器正在执行') this.age += 1; callBack(this.age); }, 1000); }, unsubscribe() {
      clearInterval(this.intervalId); }};// class Like004 extends React.Component {
      // state = {
      // age: 0// }//// componentDidMount() {
      // AgeAPI.subscribe((age) => {
      // this.setState({
      // age// })// })// }//// componentWillUnmount() {
      // AgeAPI.unsubscribe();// }//// render() {
      // return (//
      //

      我是树妖,今年{this.state.age}岁了!

      //
      //
      // );// }// }//// export default Like004;const Like004 = () => {
      const [age, setAge] = useState(0); useEffect(() => {
      AgeAPI.subscribe((currentAge) => {
      setAge(currentAge) }) // 处理副作用代码,相当于在componentWillUnmount return () => {
      AgeAPI.unsubscribe(); } }, []) return (

      我是树妖{
      age}

      )}export default Like004;

    ⑤ hook中使用网络请求

    1. 基本使用
      import React, {
      useEffect, useState} from 'react'import ajax from "../http";const Like005 = () => {
      const [data, setDate] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => {
      (async () => {
      const response = await ajax('http://demo.itlike.com/web/xlmc/api/homeApi/categoriesdetail/lk001?itlike=87224866875667849947') setDate(response.data.data); setLoading(false); })() }, []) return (
      {
      loading ?
      正在拼命加载中
      : data.cate[0].name}
      )}export default Like005;
    2. 自己包装一个钩子
      import React, {
      useEffect, useState} from 'react'import ajax from "../http";const useAjax = (url) => {
      const [data, setDate] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => {
      (async () => {
      const response = await ajax(url) setDate(response.data.data); setLoading(false); })() }, []) return {
      data, loading}}const Like005 = () => {
      const {
      data, loading} = useAjax('http://demo.itlike.com/web/xlmc/api/homeApi/categoriesdetail/lk001?itlike=87224866875667849947'); return (
      {
      loading ?
      正在拼命加载中
      : data.cate[0].name}
      )}export default Like005;

    ⑥ Hook 使用规则

    1. 只在最顶层使用 Hook
    2. 只在 React 函数中调用 Hook

    ⑦ Hook中处理副作用操作

    ⑧ 性能优化:对比文档前后,如果没有变化就不进行渲染

    1. import React from 'react'import Other from './other'// export default class Like008 extends React.Componentexport default class Like008 extends React.PureComponent{
      state = {
      age: 0 }; /* componentDidMount() { setInterval(()=>{ this.setState({ // age: this.state.age + 1 age: 100 }) }, 1000); } */ componentDidMount() {
      setInterval(()=>{
      this.setState({
      age: this.state.age + 1 }) }, 1000); } render() {
      console.log('render被调用了~~~~'); return (
      {
      this.state.age}
      ) }}
    2. React.memo

      import React from 'react'const Other = ({
      otherName})=>{
      console.log('other组件中的render被调用了'); return (

      我叫: {
      otherName}

      )};// export default Otherexport default React.memo(Other);

    ⑨ useCallback使用

    1. 示例

      const memoizedCallback = useCallback(  () => {
      doSomething(a, b); }, [a, b],);
    2. 实操

      ① 第二个参数决定了是否允许第一个参数执行
      ② 二个参数发生变化则允许执行,否则则不允许执行
      ③ 第一个参数第一次会执行一次,之后才会判断第二个参数是否发生变化然后再执行

      /*  useCallback  网址: https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback  const memoizedCallback = useCallback(  () => {    doSomething(a, b);  },  [a, b],);- 第二个参数b决定了是否允许第一个参数执行- 第一个参数第一次会执行, 之后会根据第二个参数的变化决定是否执行*/import React, {
      useState, useCallback} from 'react'const Like009 = ()=>{
      const [age, setAge] = useState(1); const [weight, setWeight] = useState(50); function clickHandler() {
      setAge(age + 1); } return (

      年龄: {

      age} 岁

      体重: {

      weight}千克

      {
      /*
      */}
      )};export default Like009;

    ⑩ usereducer [网址](https://zh-hans.reactjs.org/docs/hooks-reference.html#usereducer)

    import React, {
    useState, useReducer} from 'react'const initialState = {
    count: 0};function reducer(state, action) {
    switch (action.type) {
    case "increment": return {
    count: state.count + 1}; case "decrement": return {
    count: state.count - 1} }}function Counter() {
    const [state, dispatch] = useReducer(reducer, initialState); return (
    计算结果: {
    state.count}
    )}export default Counter;

    ⑪ usecontext

    import React, {
    useContext} from 'react'const themes = {
    dark: {
    width: 100, height: 40, borderRadius: 10, border: 'none', color: 'green', backgroundColor: 'orange' }};const ThemeContext = React.createContext();function App() {
    return (
    )}function ToolBar() {
    return (
    )}function ThemedButton() {
    const theme = useContext(ThemeContext); console.log(theme); return ( )}export default App;

转载地址:https://kaisarh.blog.csdn.net/article/details/111476948 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:React:网络工具库
下一篇:React:Redux简介

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月18日 14时11分12秒