目录
一、为什么要使用React-Hooks
1、高阶组件为了复用,导致代码层级复杂
2、生命周期的复杂
3、hooks为函数组件提供了状态
4、写成function组件,无状态组件,但是又需要状态,改成class组件成本太高
二、useState
1、useState的作用是用来声明状态变量
2、导入useState函数,调用并传入状态的初始值
3、从useState函数的返回值中,拿到状态和修改状态的方方法
4、调用修改状态的方法更新状态
三、useEffect
1、useEffect的作用是为react函数提供副作用处理
2、导入useEffect函数,调用并传入回调函数
3、在回调函数中编写副作用处理
4、修改数据状态
5、添加依赖项的几种情况
四、useCallBack
1、useCallBack的作用是为了性能的优化
2、防止因为在组件重新渲染,导致方法再次被创建,起到缓存的作用
3、通常在将一个组件中的函数,传递给子元素进行回调使用时,使用useCallback对函数进行处理
五、useMemo
1、useMemo的作用是优化子组件渲染
2、对状态数据进行计算,最终返回一个结果
3、点击按钮时,name和NameMemo会被重新赋值,NameMemo依赖name值,name值发生改变NameMemo会被重新赋值
六、useRef
1、useRef的作用是在函数组件中获取真实dom元素对象或者组件对象
2、导入useRef函数,调用useRef()方法并接收返回值
3、在获取的元素上进行绑定,通过ref属性将useRef的返回值绑定到元素身上
4、useRef返回对象的current属性对应着获取的元素
七、useContext
1、useContext的作用是跨越组件层级直接传递变量,实现数据共享
2、使用createContext创建Context对象
3、在外层组件通过Provider提供数据
4、在内层组件通过useContext函数获取数据
八、useReducer
1、useReducer的作用是修改多个state状态
2、定义[state, dispatch]来接收当前应用的state和触发的动作action,计算并返回最新的state
3、useReducer包含两个参数,一个参数为useReducer的函数,一个为初始值
4、在按钮中绑定点击事件,触发useReducer的事件需要使用dispatch
九、自定义hooks
1、必须以"use"开头
2、当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中
3、再解释:将复杂代码封装到函数中
一、为什么要使用React-Hooks
1、高阶组件为了复用,导致代码层级复杂
2、生命周期的复杂
3、hooks为函数组件提供了状态
4、写成function组件,无状态组件,但是又需要状态,改成class组件成本太高
注意:不存在生命周期
二、useState
1、useState的作用是用来声明状态变量
2、导入useState函数,调用并传入状态的初始值
3、从useState函数的返回值中,拿到状态和修改状态的方方法
4、调用修改状态的方法更新状态
注意:不能直接修改旧的状态
//导入useState import React,{useState} from 'react' const Use = () => { const [name, setname] = useState('leo')return (<div><p>{name}</p><button onClick={() => {//更新状态setname('lee')}}>按钮</button></div>) }
三、useEffect
1、useEffect的作用是为react函数提供副作用处理
2、导入useEffect函数,调用并传入回调函数
3、在回调函数中编写副作用处理
4、修改数据状态
// 导入useEffect函数 import React,{useState, useEffect} from 'react'const Use = () => { const [name,setname] = useState('leo');//副作用处理 useEffect(() => { //如果在这里对name做了修改,那么数组中必须指明对应的依赖(依赖指状态)setname(name.toUpperCase());return () => {console.log('在这里组件被销毁')} },[name]); //第二个参数如果是空数组,那么第一个参数只走一次 //如果[name] name作为依赖存在, //只要被修改,第一个参数就会走一次 //在这里可以看做是对状态数据的再次加工处理
5、添加依赖项的几种情况
(1)不添加依赖项
<1>组件第一次渲染时执行
<2>组件中任何状态更新都会重新执行
// 副作用处理 useEffect(() => {console.log('在这里组件被销毁'); })
(2)添加空数据:组件只在第一次渲染时执行一次
// 副作用处理 useEffect(() => {console.log('在这里组件被销毁'); },[])
(3)添加特定依赖项
<1>副作用函数在首次渲染时执行
<2>在依赖项发生变化时也会重新执行
// 导入useEffect函数 import React,{useState, useEffect} from 'react'const Use = () => { const [name,setname] = useState('leo');//副作用处理 useEffect(() => { //如果在这里对name做了修改,那么数组中必须指明对应的依赖(依赖指状态)setname(name.toUpperCase());return () => {console.log('在这里组件被销毁')} },[name]); //第二个参数如果是空数组,那么第一个参数只走一次 //如果[name] name作为依赖存在, //只要被修改,第一个参数就会走一次 //在这里可以看做是对状态数据的再次加工处理return (<div><p>{name}</p><button onClick={() => {// 更新状态setname('lee')}}>按钮</button></div>) }
四、useCallBack
1、useCallBack的作用是为了性能的优化
2、防止因为在组件重新渲染,导致方法再次被创建,起到缓存的作用
3、通常在将一个组件中的函数,传递给子元素进行回调使用时,使用useCallback对函数进行处理
const [name,setname] = useState('lee'); const myFn = useCallBack(() => {console.log(name); },[name]) //只有name改变,函数才会重新生成一次 //如果传入空数组,函数首次执行生成,之后不变 //如果不传数组,每次都会生成新的函数
五、useMemo
1、useMemo的作用是优化子组件渲染
2、对状态数据进行计算,最终返回一个结果
3、点击按钮时,name和NameMemo会被重新赋值,NameMemo依赖name值,name值发生改变NameMemo会被重新赋值
import './App.css'; import React from 'react' function App() {let [name, setname] = React.useState('leo')const changeName = () => {setname("lee")}const NameMemo = React.useMemo(()=>name+'小红',[name])return (<div><h1>我的名字是:{name}</h1><button onClick={changeName}>点击改变name</button><h1>小红的名字是:{NameMemo}</h1></div>); } export default App;
六、useRef
1、useRef的作用是在函数组件中获取真实dom元素对象或者组件对象
2、导入useRef函数,调用useRef()方法并接收返回值
3、在获取的元素上进行绑定,通过ref属性将useRef的返回值绑定到元素身上
4、useRef返回对象的current属性对应着获取的元素
//导入useRef函数 import React, {useRef} from 'react'const Useref = () => {const Dwh = useRef();const Ps = Dwh.current.querySelectorAll('p')console.log(Dwh);console.log(Ps);return (<div ref={Dwh}><p></p><p></p><p></p></div>) }export default Useref
七、useContext
1、useContext的作用是跨越组件层级直接传递变量,实现数据共享
2、使用createContext创建Context对象
3、在外层组件通过Provider提供数据
4、在内层组件通过useContext函数获取数据
//导入useContext函数 import { createContext, useContext } from 'react' // 创建Context对象 const Context = createContext() function App() { return ( // 外层组件通过Provider提供数据 <Context.Provider value={'传递数据'}> <div><choo /></div> </Context.Provider> ) }function choo() { // 内层组件通过useContext函数获取数据 const data = useContext(Context) return (<div>{data}</div>) }
八、useReducer
1、useReducer的作用是修改多个state状态
2、定义[state, dispatch]来接收当前应用的state和触发的动作action,计算并返回最新的state
3、useReducer包含两个参数,一个参数为useReducer的函数,一个为初始值
4、在按钮中绑定点击事件,触发useReducer的事件需要使用dispatch
//dispatch:发送信号执行外部的reducer方法const [state,dispatch] = useReducer(reducer,intailState);<button onClick = {() => {dispatch({type: 'key1'}) }}> </button>
//导入useReducer函数 import React, { useReducer } from 'react'//处理函数 const reducer = (prevState,action) => {let state = {...prevState}; //prevState 只读switch(action.key){case 'key1':代码1;break;case 'key2':代码2;break;default:break;}return state; } //外部对象 const intailState = {count: 0 }
注意:useReducer + useContext 解决大量组件传值问题
九、自定义hooks
1、必须以"use"开头
2、当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中
3、再解释:将复杂代码封装到函数中