提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
目录
1.useState
hook只能写在函数组件里面
useState
是react自带的一个hook函数,它的作用是用来声明状态变量。
useState和类组件的this.state一样,都是用来管理组件状态的。在React Hook没出来之前,函数组件也叫做Functional Stateless Component(FSC:功能无状态的组件),这是因为函数组件每次执行的时候都会生成新的函数作用域所以同一个组件的不同渲染(render)之间是不能够共用状态的,因此开发者一旦需要在组件中引入状态就需要将原来的函数组件改成类组件,这使得开发者的体验十分不好。useState就是用来解决这个问题的,它允许函数组件将自己的状态持久化到React运行时的某个地方,这样在组件每次重新渲染的时候都可以从这个地方拿到该状态,而且当该状态被更新的时候,组件也会重渲染。
应用示例如下:
import React,{ useState } from "react"; // 函数组件 function App(){ // 解构赋值 let [count,setCount]=useState(10) let [p,setP]=useState({x:40,y:50}) let change2=()=>{ // setP({x:100,y:200}) setP({y:120}) //全量替换:{y:120}会把原来的{x:100,y:200}直接替换了 } return ( <div> <p>{count}</p> <button onClick={()=>setCount(count+1)}>change</button> <p>{p.x}--{p.y}</p> <button onClick={()=>{setP({x:20,y:30})}}>change2</button> </div> ) } export default App;
setState是全量替代(面试)
函数组件的setState和类组件的this.setState函数的一个重要区别是:
类组件是将当前设置的state浅归并到旧state的操作。而hook的setState函数则是将新state直接替换旧的state。
setState没有回调函数(面试)
无论是useState还是类组件的this.setState都是异步调用的,也就是说每次组件调用完之后都不能立即拿到最新的state值。
为了解决这个问题,类组件的this.setState允许通过一个回调函数来获取到最新的state值:this.setState(newState, state => { console.log( state)})
const [ count , setCount ] = useState(0); //ES6语法中的数组解构赋值
等于
let _useState = userState(0) let count = _useState[0] let setCount = _useState[1]
useState
这个函数接收的参数是状态的初始值(Initial state),它返回一个数组,这个数组的第0位是当前的状态值,第1位是可以改变状态值的方法函数。
2.useEffect
useEffect是用来使函数组件也可以进行副作用操作的。
useEffect意思是用于处理组件中的副作用,用来取代生命周期函数。
useEffect(()=>{//副作用函数 return ()=>{ // 返回函数 } },[依赖参数])
useEffect的用法
useEffect就是指定一个副效应函数,组件每渲染一次,该函数就自动执行一次。组件首次在网页 DOM 加载后,副效应函数也会执行。
useEffect用处
在react中,可以在生命周期中执行副作用操作,在react hooks中,可以在useEffect中执行副作用操作。
useEffect执行时机
可以看做 react 中componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个生命周期函数的组合,也就是在这三个时候会执行。
useEffect示例应用如下:
export default function App() { let [msg,setMsg]=useState("") useEffect(()=>{ console.log("App组件对应的模板加载时运行") fetch("http://192.168.60.23:7001/test1") .then(res=>res.json()) .then(data=>{ console.log(data) setMsg(data[0].title) }) }) useEffect(()=>{ console.log(1234567) }) }
(2.1)useEffect可以做什么?
(1)挂载阶段:
从上向下执行函数,如果碰到 useEffect 就执行并将 useEffect 传入的副作用函数推入一个队列(链表),在组件挂载完成之后,将队列(链表)中的副作用函数执行,并将副作用函数的返还函数,推入一个新的队列(链表)(2)更新阶段 - !!! 更新阶段不同于其他阶段对应的函数是否要执行,取决于依赖参数:
从上向下执行函数,如果碰到 useEffect 就执行并将 useEffect 传入的副作用函数推入一个队列(链表),在组件更新完成之后,找出之前的返回函数队列,依次准备执行,在执行前会判断该 useEffect 的依赖参数,如果依赖参数改变就执行,否则跳过当前项去看下一项,然后再执行副作用队列,执行时同样判断依赖是否变化,来决定其是否执行,如果执行,就重新获取其对应的返回函数。(3)卸载阶段:
组件即将卸载时,找出其对应的返回函数队列,依次执行
(2.2)处理副作用的几种情况
依赖参数不同时有不同的效果:
为空: 组件的任何更新,该 useEffect 对应的返回函数和函数都执行
为空数组: 不监听组件的更新
数组中有具体依赖:对应的依赖数据,有变化的时候,才会执行
(2.3)useEffect 的总结
useEffect(() => { }) //每次组件渲染都执行
useEffect(() => { return () => { } }, []) //组件第一次渲染执行,组件移除时触发clean函数
useEffect(() => { return () => { } }, [count])//count改变才会执行,组件重新渲染前触发clean函数