目录
4、写成function组件,无状态组件,但是又需要状态,改成class组件成本太高
3、从useState函数的返回值中,拿到状态和修改状态的方方法
1、useEffect的作用是为react函数提供副作用处理
2、防止因为在组件重新渲染,导致方法再次被创建,起到缓存的作用
3、通常在将一个组件中的函数,传递给子元素进行回调使用时,使用useCallback对函数进行处理
3、点击按钮时,name和NameMemo会被重新赋值,NameMemo依赖name值,name值发生改变NameMemo会被重新赋值
1、useRef的作用是在函数组件中获取真实dom元素对象或者组件对象
2、导入useRef函数,调用useRef()方法并接收返回值
3、在获取的元素上进行绑定,通过ref属性将useRef的返回值绑定到元素身上
4、useRef返回对象的current属性对应着获取的元素
1、useContext的作用是跨越组件层级直接传递变量,实现数据共享
2、定义[state, dispatch]来接收当前应用的state和触发的动作action,计算并返回最新的state
3、useReducer包含两个参数,一个参数为useReducer的函数,一个为初始值
4、在按钮中绑定点击事件,触发useReducer的事件需要使用dispatch
一、为什么要使用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、再解释:将复杂代码封装到函数中