react-Hooks

Hooks:钩子,是React16.8中的新功能

Hooks作用:

1、组件的逻辑状态复用

(1)在Hooks之前,组件的状态逻辑复用经历了:mixins(混入)、HOCs(高阶组件)、render-props等模式

(2)(早已废弃)mixins的问题:数据来源不清晰、命名冲突

(3)HOCs(高阶组件)、render-props的问题:重构组件结构,导致组件形成jsx嵌套地狱问题

2、class组件自身问题

(1)选择:函数组件和class组件之间的区别以及使用

(2)需要理解class中的this是如何工作的

(3)互相关联且需要对照修改的代码被拆分到不同生命周期函数中

相比于函数组件来说,不利于代码压缩和优化,也不利于ts的类型推导

Hooks渐进式使用

class组件相关的API在hooks中可以不用

(1)class自身语法,比如,constructor、static

(2)钩子函数,componentDidMount、componentDidUpdate、componentWillUnmount

(3)this相关语法

class继续使用的语法

(1)JSX:{},onClick(),条件渲染、列表渲染、样式处理

(2)组件:函数组件、组件通讯

(3)React开发理念:单向数据流、状态提升

useState基本使用

1、使用useState为函数组件提供状态

2、内容:

(1)一个hook就是一个特殊的函数,让函数组件中获取状态等react特性.从名称上来看hook都以use开头

(2)useState的使用场景:当想要的函数组件中,使用组件状态时,就要使用useState Hook了

(3)useState作用:为函数组件提供状态

(4)参数:状态初始值

(5)返回值:stateArray是一个数组

import { useState } from 'react'

const Parent = () => {
  // // 调用useState  hook创建状态
  // // const stateArray=useState(10)
  // const stateArray=useState(10)
  // // 拿到state状态
  // const state=stateArray[0]
  // // 拿到修改状态的函数
  // const setState=stateArray[1]
  const [state, setState] = useState(10)
  const [user, setUser] = useState({ name: 'ii', age: 99 })
  return (
    <>
      我是parent组件,我在试验useState属性的使用
      <span>{state}</span>
      <button onClick={() => setState(state + 1)}>点击</button>
      <br />
      <p>{user.name}</p>
      <p>{user.age}</p>
      <button onClick={() => setUser({ ...user, age: 55 })}>点击</button>
      <button onClick={() => setUser({ name: 'uu', age: 55 })}>点击</button>
    </>
  )
}

export default Parent

3、useState是进行覆盖的操作

4、组件渲染规则

4.1组件第一次渲染

(1)从头开始执行该组件中的代码逻辑

(2)调用useState(0)将传入的参数作为状态初始值,即:0

(3)渲染组件时,获取到的数据状态是初始值0

4.2组件第二次渲染

(1)点击按钮,调用setCount(count+1)修改状态,因为状态发生改变,所以,该组件会重新渲染

(2)组件重新渲染时,会再执行该组件的代码逻辑

(3)再次调用useState(0),此时React内部会拿到最新的状态而非初始值,比如,该案例中最新的状态值是1

(4)再次渲染组件,此时,获取到的状态count值为1

4.3注意

useState的初始值指挥在第一次渲染组件时生效

useEffect副作用介绍

1、副作用定义:在计算机中,如果一个函数或其他操作修改了局部环境之外的状态变量值,那么他就被称为有副作用。

对于React组件来说,主作用就是根据数据渲染UI,除此之外都是副作用(比如,手动修改DOM)

常见副作用:ajax请求,手动修改DOM,localStorage,console.log操作

2、useEffect第二个参数:表示effect的依赖项

只有数组中的依赖项改变时effect回调才会执行

import {useState,useEffect } from "react";

const Parent =()=>{
  const [user,setUser]=useState({name:'oo',age:66})
  const [count,setCount]=useState(0)
  // useEffect用法一
  useEffect(()=>{
    document.title='yyyy'
  })
  // useEffect用法二
  useEffect(()=>{
    localStorage.setItem('setUser','hooks')
  })
  // useEffect带第二个参数的用法
  useEffect(()=>{
    document.title=`${count}次被点击`
  },[count])
  return (
    <>
    我是parent组件
    <p>{user.name}</p>
    <button onClick={()=>setUser({...user,name:'yyyy'})}>点击</button>
    <br />
    <p>{count}</p>
    <button onClick={()=>setCount(count+1)}>点击</button>
    </>
  )
}

export default Parent

3、useEffect解绑事件监听

  useEffect(()=>{
    const onReize=()=>{
      console.log('onresize');
    }
    window.addEventListener('resize',onReize)
    // 1、使用effect回调函数的返回值,来执行清理监听事件操作
    return ()=>{
      window.removeEventListener('resize',onReize)
    }
  },[count])

4、useEffect中发起异步请求

  // useEffect不能有异步请求,所以需要在里面自定义异步函数并调用
  useEffect(()=>{
    const loadData=async()=>{
      console.log('loadData');
    }
    loadData()
  })

5、effect对依赖项撒谎

如果 useEffect 回调函数中用到了某个数据,但是,没有出现在依赖项数组中,就会导致一些 Bug 出现

useContext

一、回顾context

1、作用:实现跨组件传递数据,而不必在每个级别手动传递props,简化组件之间得数据传递过程

2、context对象包含了两个组件

<Context.Provider value>:通过value属性提供数据

<Context.Consumer>:通过render-props模式,在JSX中获取Context中提供数据

3、默认值

提供默认值时需要让默认值得结构与Provider提供得value值结构保持一致

默认值生效得时机:当在使用Context对象得时候,如果没有提供Provider,此时得默认值生效

  1
import { createContext, useState } from "react";

const ColorContext = createContext({
  color: "red",
  setColor: () => {},
});

const List = ({ children }) => {
  return (
      3
    <ColorContext.Consumer>
      {(value) => (
        <>
          <p>list组件{value.color}</p>
          <p>{children}</p>
          <button onClick={() => value.setColor("blue")}>
            点击修改color数据
          </button>
        </>
      )}
    </ColorContext.Consumer>
  );
};

const Child = () => {
  return <List>我是child传过来的</List>;
};

const Parent = () => {
  const [color, setColor] = useState("green");
  console.log(color);
  return (
    <>
      {/*   2 */}
      <ColorContext.Provider value={{ color, setColor }}>
        <p>{color}</p>
        <Child></Child>
      </ColorContext.Provider>
    </>
  );
};

export default Parent;

 二、useContext

和context区别:获取位置不同,context只能在JSX中获取。useContext可以在JS和JSX中获取。

/第一步:书写公共引入样式
import { createContext, useContext, useState } from "react";
const ColorContext = createContext();

const List = () => {
  /第三步:使用useContext接收传入的参数
  const { color, setColor } = useContext(ColorContext);
  console.log(color);
  return (
    <>
      <p>我是list组件---{+color}</p>
      {/* /第四步:使用数据 */}
      <button onClick={() => setColor(!color)}>点击改变color</button>
    </>
  );
};

const Child = () => {
  return (
    <>
      <List></List>
      <p>我是child组件</p>
    </>
  );
};

const Parent = () => {
  const [color, setColor] = useState(true);
  return (
    <>
      {/* /第二步:提供传入的参数 */}
      <ColorContext.Provider value={{ color, setColor }}>
        <Child></Child>
      </ColorContext.Provider>
      <p>我是parent组件</p>
    </>
  );
};

export default Parent;

 useRef

使用场景:在React中进行DOM操作,用来获取DOM。

作用:返回一个带有current属性的可变对象,通过该对象就可以进行DOM操作了。

import { useRef } from "react"

const Parent=()=>{
  /第一步:使用useRef创建一个ref对象
  const inputRef=useRef(null)
  const add=()=>{
    /第三步:通过inputRef.current来访问对应的DOM
    console.log(inputRef.current.value);
    inputRef.current.focus()
  }
  return (
    <>
    <div>useRef的使用</div>
    {/* /第二步:将ref对象设置为input的ref属性值,
        目的:将ref对象关联到input对应的DOM对象身上 */}
    <input type="text" placeholder="请输入内容" ref={inputRef}/>
    <button onClick={add}>点击</button>
    </>
  )
}

export default Parent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值