07 hook学习01

Hooks理解

react组件分为类组件和函数组件

函数组件是一个更加匹配react的设计理念UI = f(data),利于逻辑拆分与重用的组件表达形式,而之前的函数组件是不可以有自己的状态的,为了能让函数组件可以拥有自己的状态,react16.8开始,Hooks出现

  • Hooks出现后,类组件并没有移除,还是可以使用
  • Hooks出现有,不能把函数成为无状态组件
  • Hooks只能在函数组件中使用

Hooks出现解决的问题:

1,组件的状态逻辑复用

2,claas组件自身的问题

  • 告别难以理解的Class
  • 解决业务逻辑难以拆分的问题
  • 使状态逻辑复用变得简单可行
  • 函数组件在设计思想上,更加契合react理念

useState

提供一个状态,以及修改状态的方法,useState后的值表示初始化的值

// useState
// 1,导入useState函数 react
// 2,执行这个函数并且传入初始值,必须在函数组件中
// 3,[数据,修改数据的方法]
// 4,使用数据,修改数据
import { useState } from 'react'
function App () {
  // useState返回一个数组,如下是结构赋值的写法
  // 名字是可以自定义的 -> 保持语义化
  // 顺序不可以换,数组是有序的,第一个参数是数据状态,第二个参数就是修改数据的方法
  // setCount是一个函数,作用: 用于修改count状态的值,依旧保持不能直接修改原值,还是用于计算得到的新值替换原值
  // count和setCount是绑在一起的
  const [count, setCount] = useState(0)
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>{count}</button>
    </div>
  )
}

更新过程:

// 当调用setCount时,更新过程

// 首次渲染
/**
 * 首次被渲染时,组件内部的代码会被执行一次
 * 其中useState也会跟着执行
 * useState(0)初始值,只在首次渲染时生效
 */

// 更新渲染
/**
 * setCount都会更新
 * APP组件会再次渲染,这个函数会再次执行
 * useState再次执行得到的新的count执行不是0,而是修改后的1,模板会使用新值
 */

useState调用多次,初始化多个状态

function App () {
  const [count, setCount] = useState(0)
  const [flag, setFlag] = useState(true)
  const [list, setList] = useState([1, 2, 3])
  console.log(count)
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      {list.map(item => <h2 key={item}>{item}</h2>)}
    </div>
  )
}

注意事项:

  • 只能出现在函数组件中

  • 不能嵌套在if/for/其他函数中(react按照hooks的调用顺序识别每一个hook),如下是错误写法

    let name = 'seek'
    function Show(){
    	name = 'seek18'
    	// 错误写法
    	if (name = 'seek18'){
    		const [age,setAge] = useState(18)
    	}
    	const [flag,setFlag] = useState(true)
    }
    

    可以通过开发者工具查看hook状态

在这里插入图片描述

useEffect

函数的副作用:

一个函数除了主作用,其他的作用就是副作用,对于react组件来说,主作用就是根据数据渲染UI,除此以外都是副作用(例如:手动修改DOM)

常见的副作用:

  • ajax请求
  • 手动修改dom
  • localstorage操作

useEffect函数的作用就是为react函数组件提供副作用处理

import { useEffect, useState } from 'react'

// 在修改数据后,把count值放到页面标题中
// 1,导入useEffect函数
// 2,在函数组件中执行
// 3,当我们通过修改状态更新组件时,副作用也不断执行
function App () {
  const [count, setCount] = useState(0)
  useEffect(() => {
    document.title = count
  })
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>{count}</button>
    </div>
  )
}

export default App

通过依赖项,控制执行实际

1,默认状态
2,添加一个空数组
3,依赖特性项
function App () {
  const [count, setCount] = useState(0)
  const [name, setName] = useState('seek')

  // 默认:组件第一次渲染以及每次更新执行
  useEffect(() => {
    document.title = count
    console.log('每次执行')
  })

  // 只会在首次渲染执行
  useEffect(() => {
    console.log('first console')
  }, [])

  // 添加特定的依赖项,表示只有修改count才会执行,后面是一个数组
  useEffect(() => {
    console.log('count console')
  }, [count])

  // 同时修改count和name,或者只改一个都会执行
  useEffect(() => {
    console.log('count console')
  }, [count,name])

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      <button onClick={() => setName(name + 'a')}>{name}</button>
    </div>
  )
}

注意事项:

useEffect 回调函数中用到的数据(比如,count)就是依赖数据,就应该出现在依赖项数组中,如果不添加依赖项就会有bug出现

hook的出现,就是不想用生命周期概念,也可以写业务代码

自定义hook函数

自定义一个hook函数,实现获取滚动距离Y,const [y] = useWindowScroll()

import { useEffect, useState } from 'react'

function useWindowScroll () {
  const [y, setY] = useState(0)
  window.addEventListener('scroll', () => {
    const h = document.documentElement.scrollTop
    setY(h)
  })
  return [y]
}

function App () {
  const [y] = useWindowScroll()
  return (
    <div style={
   
   { height: '12000px' }}>
      {y}
    </div>
  )
}


export default App

自定义hook函数,可以自动同步到本地LocalStorage

const [message, setMessage] = useLocalStorage(key,defaultValue)

function useLocalStorage (key, defaultValue) {
  const [message, setMessage] = useState(defaultValue)
  useEffect(() => {
    window.localStorage.setItem(key, message)
  }, [key, message])
  return [message, setMessage]
}

猜你喜欢

转载自blog.csdn.net/qq_39225271/article/details/127183056