HOOK
react HOOK 是react16.8新增的一个特性 主要作用 就是让无状态组件/函数组件 可以使用状态 ref等一些特性
HOOK 不能在 class组件中使用
类组件与函数组件的区别
无状态组件 的创建比类组件的可读性更好 就是大大减少了组件编写代码量 在组件内容只有一个jsx编写效率更高
函数组件中不用this 因为函数组件没有实例化的过程
useState
useState 是reactHOOK给我们提供的 最基本最常用的一个HOOK 主要作用就是用来管理当前本地的状态
useState() 返回值是一个数组(长度为2)数组的第一项标识的是当前的值 数组的第二项标识的时候修改这个值的函数
let [xiaoming , setXiaoming]=useState(初始值)
创建与读取
1 2 3 4 5 6 7 8 9 10 11 12
| import {useState} from "react" let Funcom=()=>{ let [xiaoming,setxiaoming]=useState("你好么么哒!!!") return ( <div> {/* 读取 */} <h1>我是一个函数组件--{xiaoming}</h1> </div> ) } export default Funcom
|
修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import {useState} from "react" let Funcom=()=>{ let [xiaoming,setxiaoming]=useState("你好么么哒!!!") return ( <div> {/* 读取 */} <h1>我是一个函数组件--{xiaoming}</h1> {/* 修改数据 */} <button onClick={()=>{setxiaoming(xiaoming="你好呵呵哒")}}>点我修改</button> </div> ) } export default Funcom
|
创建多个状态呢
1.你写多个useState
1 2 3 4 5 6 7 8 9 10 11 12 13
| import {useState} from "react" let Funcom=()=>{ let [xiaoming,setxiaoming]=useState("1") let [xiaohong,setxiaohong]=useState("2") return ( <div> {xiaoming}---{xiaohong} </div> ) } export default Funcom
|
2.一次行创建多个值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import {useState} from "react" let Funcom=()=>{ let [xiaoming,setxiaoming]=useState({ dataa:"第一个值1", datab:"第一个值2", datac:"第一个值3", datad:"第一个值4", datae:"第一个值5", dataf:"第一个值6" }) return ( <div> {/* {xiaoming}---{xiaohong} */}
{xiaoming.dataa}----{xiaoming.datad} </div> ) } export default Funcom
|
一次性创建多个值怎么修改
1.多个useState 要修改的话就依次调用其中的修改方法
2.一次行创建多个值的方式如何修改呢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import {useState} from "react" let Funcom=()=>{ let [xiaoming,setxiaoming]=useState({ dataa:"第一个值1", datab:"第一个值2", datac:"第一个值3", datad:"第一个值4", datae:"第一个值5", dataf:"第一个值6" })
let fun=()=>{ setxiaoming({...xiaoming,datad:"我被改了"}) }
return ( <div> {/* {xiaoming}---{xiaohong} */}
{xiaoming.dataa}----{xiaoming.datad} <button onClick={fun}>点我修改</button> </div> ) } export default Funcom
|
useRef
就是可以让函数组件使用ref的一个技术
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import {useRef} from "react" let Funcom=()=>{
let xiaoming=useRef(null)
let fun=()=>{ console.log(xiaoming.current.value); } return ( <div> {/* 2.绑定使用 */} <input type="text" ref={xiaoming}/> <button onClick={fun}>点我得到输入框的值</button> </div> ) } export default Funcom
|
useEffect
Function Component 不存在生命周期,所以不要把 Class Component 的生命周期概念搬过来试图对号入座。
useEffect就可以让函数组件使用生命周期
语法:
1
| useEffect(第一个参数是一个函数,第二个参数是一个数组)
|
就是如下三个钩子函数的综合体
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| componentDidMount() {
}
componentDidUpdate() {
}
componentWillUnmount() {
}
|
模拟componentDidMount
useEffect(()=>{console.log(‘第一次渲染时调用’)},[])
第二个参数为一个空数组,可以模拟componentDidMount
因为函数组件每次更新的时候就是组件会被全部调用一次 传递了空数组就相当于欺骗了react我要监听某个内容 所以只是第一次调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import {useEffect} from "react" let Funcom=()=>{ useEffect(()=>{ document.title="么么哒" console.log("我自动执行了"); },[]) return ( <div> <h1>函数组件可以使用生命周期</h1> </div> ) } export default Funcom
|
模拟componentDidUpdate
没有第二个参数代表监听所有的属性更新但是注意首次也会触发
因为函数组件每次更新的时候就是组件会被全部调用一次 什么都不传那么每次修改就会触发
1
| useEffect(()=>{console.log('任意属性该改变')})
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import React, { useState, useEffect } from 'react'
export default function Demo() { let [xiaoming, setXiaoming] = useState("666") useEffect(() => { console.log("谁修改我都会触发") }) let fun = () => { setXiaoming("我变了") } return ( <> <div>demo--{xiaoming}</div> <button onClick={fun}>点我修改</button> </> ) }
|
监听多个属性的变化需要将属性作为数组传入第二个参数。
因为函数组件每次更新的时候就是组件会被全部调用一次 传递了值就会告诉react我要监听某个内容 所以只有这些值改变的时候就会被调用
1
| useEffect(()=>{console.log('n变了')},[n,m])
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React, { useState, useEffect } from 'react'
export default function Demo() { let [xiaoming, setXiaoming] = useState("666") let [xiaohong, setXiaohong] = useState("777") useEffect(() => { console.log("谁修改我都会触发") },[xiaohong]) let fun = () => { setXiaoming("我变了") } return ( <> <div>demo--{xiaoming}--{xiaohong}</div> <button onClick={fun}>点我修改</button> </> ) }
|
模拟componentWillUnmount
通常,组件卸载时需要清除 effect 创建的诸如订阅或计时器 ID 等资源
useEffect函数返回的函数可以表示组件死亡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import React,{useState,useEffect} from 'react'
function Zi() { useEffect(()=>{ let time= setInterval(()=>{ console.log("你好") },1000) return ()=>{ console.log("我被销毁了") clearInterval(time) } }) return ( <div>我是Zi组件</div> ) }
export default function Demo() { let [bool,setbool]=useState(true) return ( <div> 我是父组件 <button onClick={()=>{setbool(!bool)}}>点我显示和隐藏子组件</button> {bool&& <Zi></Zi>} </div> ) }
|
useContext
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。
可以直接获取到context对象的Consumer消费者中的数据
在没有使用的时候跨组件传值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import React, { createContext } from 'react' let context = createContext() function Sun() { return ( <div> 孙 <context.Consumer> { (value)=>{ return ( <h1>{value.name}</h1> ) } } </context.Consumer> </div> ) }
function Zi() { return ( <div> 子 <Sun></Sun> </div> ) }
export default function Fu() { return ( <context.Provider value={{name:"xiaoyang",age:18}}> <div> 父 <Zi></Zi> </div> </context.Provider> ) }
|
使用useContext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React, { createContext,useContext } from 'react' let context = createContext() function Sun() { let value=useContext(context) return ( <div> 孙 <h1>{value.name}</h1> </div> ) }
function Zi() { return ( <div> 子 <Sun></Sun> </div> ) }
export default function Fu() { return ( <context.Provider value={{name:"xiaoyang",age:18}}> <div> 父 <Zi></Zi> </div> </context.Provider> ) }
|
useReducer
就是在react中 函数组件如果对一个state有多次修改 那么可以使用useReducer来对其内容进行简化
语法:
let [保存这个值得变量,是对这个变量修改的一个方法]=useReducer(修改数据的reducer方法,”初始化值”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| import {useReducer} from "react" let Funcom=()=>{ let [state,dispatch]=useReducer(reducer,18) function reducer(state,action){ switch (action.type) { case "ADD": return state+1 break; case "DEL": return state-1 break; default: return state break; } } var add=()=>{ dispatch({type:"ADD"}) } var del=()=>{ dispatch({type:"DEL"}) } return ( <div>
<h1>useReducer--{state}</h1> <button onClick={add}>+1</button> <button onClick={del}>-1</button> </div> ) }
export default Funcom
或者 import {useReducer} from "react" let Funcom=()=>{ var reducer=(state,action)=>{ switch (action.type) { case "ADD": return state+1 break; case "DEL": return state-1 break; default: return state break; } } let [state,dispatch]=useReducer(reducer,18) var add=()=>{ dispatch({type:"ADD"}) } var del=()=>{ dispatch({type:"DEL"}) } return ( <div>
<h1>useReducer--{state}</h1> <button onClick={add}>+1</button> <button onClick={del}>-1</button> </div> ) }
export default Funcom
|