React-Hooks进阶:useContext、useState回调、useEffect发送网络请求和useRef

在这里插入图片描述

欢迎来到我的博客
博主是一名大学在读本科生,主要学习方向是前端。
目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
目前正在学习的是 R e a c t 框架 React框架 React框架,中间穿插了一些基础知识的回顾
博客主页codeMak1r.小新的博客

本文目录

  • Hooks进阶
    • 1.useState - 回调函数的参数
      • 来个需求
    • 2.useEffect - 清理副作用
    • 3.useEffect - 发送网络请求
    • 4.useRef
    • 5.useContext

本文被专栏【React–从基础到实战】收录

坚持创作✏️,一起学习,码出未来‍!
React-Hooks进阶:useContext、useState回调、useEffect发送网络请求和useRef_第1张图片

Hooks进阶

1.useState - 回调函数的参数

阶段目标:能够理解useState回调函数作为参数的使用场景

使用场景

参数只会在组件初次渲染中起作用,后续渲染时会被忽略。如果初始 state 需要通过计算才能获得,则可以传入一个函数,在函数中计算并返回初始的state,此函数只在初始渲染时被调用

语法

const [ name, setName ] = useState( () => {
	// 在这里编写计算逻辑  
	return '计算之后的初始值'
})

语法规则

  1. 回调函数 return 出去的值将作为 name 的初始值
  2. 回调函数中的逻辑只会在组件初始化的时候执行一次

语法选择

  1. 如果就是初始化一个普通的数据,直接使用useState(defaultValue)即可
  2. 如果要初始化的数据无法直接得到,需要通过计算得到,使用useState( () => {} )

来个需求

页面中存在两个按钮,一个初始值为10,另一个初始值为20;另外两个按钮点击后都会有自增+1的效果。

React-Hooks进阶:useContext、useState回调、useEffect发送网络请求和useRef_第2张图片

// Counter组件
import { useState } from 'react'

export default function Counter(props) {
  const [count, setCount] = useState(() => {
    // 回调形式的useState,返回值为初始值
    return props.count
  })
  return (
    <button style={{
      backgroundColor: 'skyblue', width: '100px', height: '60px', margin: '20px'
    }} onClick={() => setCount(count + 1)}>{count}</button>
  )
}
// App组件
import React, { Fragment } from 'react'
import Counter from './components/11_hooks_Counter'

export default function App() {
  return (
    <div>
      <Counter count={10} />
      &nbsp;&nbsp;
      <Counter count={20} />
    </div>
  )
}

2.useEffect - 清理副作用

阶段目标:能够掌握清理useEffect的方法

使用场景

在组件被销毁时,如果有些副作用操作需要被清理,就可以使用此语法,比如常见的定时器

语法及规则

useEffect(() => {
	console.log("副作用函数执行了!")
	// 副作用函数的执行时机为:在下一次副作用函数执行之前执行
	return () => {
		console.log("清理副作用的函数执行了!")
		// 在这里写清理副作用的代码
	}
})

定时器小案例

添加副作用函数前:组件虽然已经不显示了,但是定时器依旧在运行

import { useEffect,useState } from 'react'
function Foo() {
	useEffect( () => {
		let timer = setInterval( () => {
			console.log('副作用函数执行了')
		}, 1000)
		return () => {
		clearInterval(timer)
	}
	}, [])
}

添加清理副作用函数后:一旦组件被销毁,定时器也被清理

3.useEffect - 发送网络请求

阶段目标:能够掌握使用useEffect hook 发送网络请求

使用场景

如何在useEffect中发送网络请求,并且封装同步 async/await 操作

语法要求

不可以直接在useEffect的回调函数外层直接包裹 await,因为异步会导致清理函数无法立即返回

useEffect(async () => {
	const res = await axios.get('http://geek.itheima.net/v1_0/channels')
	console.log(res)
},[])

正确写法

在内部单独定义一个函数,然后把这个函数包装成同步

useEffect(() => {
  async function fetchData() {
    const res = await axios.get('http://geek.itheima.net/v1_0/channels')
    console.log(res)
  }
  fetchData()
}, [])

4.useRef

阶段目标:能够掌握使用useRef获取真实dom或组件实例的方法

使用场景

在函数组件中获取真实的dom元素对象或者组件对象

使用步骤

  1. 导入useRef函数
  2. 执行useRef函数并传入null,返回值为一个对象,内部有一个current属性存放拿到的dom对象(组件实例)
  3. 通过ref绑定要获取的元素或者组件

获取dom

import { useEffect, useRef } from 'react'
function App() {  
    const h1Ref = useRef(null)  
    useEffect(() => {    
        console.log(h1Ref)  
    },[])  
    return (    
        <div>      
            <h1 ref={ h1Ref }>this is h1</h1>    
        </div>  
    )
}
export default App

获取组件实例

函数组件由于没有实例,不能使用ref获取,如果想获取组件实例,必须是类组件

class Foo extends Component {  
    sayHi = () => {    
        console.log('say hi')  
    }  
    render(){    
        return <div>Foo</div>  
    }
}
    
export default Foo
import { useEffect, useRef } from 'react'
import Foo from './Foo'
function App() {  
    const h1Foo = useRef(null)  
    useEffect(() => {    
        console.log(h1Foo)  
    }, [])  
    return (    
        <div> <Foo ref={ h1Foo } /></div>  
    )
}
export default App

5.useContext

阶段目标:能够掌握hooks下的context的使用方式

React-Hooks进阶:useContext、useState回调、useEffect发送网络请求和useRef_第3张图片

实现步骤

  1. 使用createContext创建context对象
  2. 在顶层组件通过Provider提供数据
  3. 在底层组件通过useContext函数获取数据

代码实现

import { createContext, useState, useContext } from 'react'

const Context = createContext()
export default function Demo() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <Context.Provider value={count}>
        <ComA />
      </Context.Provider>
    </div>
  )
}

function ComA() {
  return (
    <div>
      <ComB />
    </div>
  )
}

function ComB() {
  const count = useContext(Context)
  return (
    <div>
      <h2>我是ComB组件,我爷爷传给我的context值为:{count}</h2>
    </div>
  )
}

如果有后代组件不在同一个文件中,只需要把创建的Context容器对象暴露出去即可。

export const Context = createContext()

在其他组件的文件中使用:

import React, { useContext } from 'react'
import { Context } from './index'
export default function ComC() {
  const count = useContext(Context)
  return (
    <div>
      {count}
    </div>
  )
}

你可能感兴趣的:(React--从基础到实战,react.js,javascript,前端)