React_hooks
React16.8新增的特性,主要针对函数组件
一、函数组件和类组件的区别
- 函数组件的运行速度比类组件更快,区别于类,没有this的概念,所以无法存储状态,但相比类组件更轻便,速度更快。
- 类组件生命周期,生命周期中有constructor,constructor中有this.state,这里可以存储组件的状态,在特定的场景做特定的事,但是占用内存相对更大,所以速度相对较慢。
16.8中hooks的出现,让函数组件拥有类组件的一些特性
二、Hooks的API
(一)useState
useState使得函数组件拥有状态,方法的参数是状态值,返回值是一个数组,数据中有两个属性。
例:count为数值,setCount为修改数值的函数。
import React, { useState } from "react"
export default function App(){
let [count,setCount] = useState(10);
function handleAdd(){
setCount(count + 1);
}
return <div>
<h2>{count}</h2>
<button onClick={handleAdd}></button>
</div>
}
- 上面的handleAdd(),也可以写为:
function handleAdd(){
setCount(()=>{
return count+1;
})
}
注意:只有内存地址发生改变的时候,页面才会更新。所以,当涉及到对象、数组等操作时,建议先将其解构出来。
import React, { useState } from "react"
export default () => {
let [obj, setObj] = useState({ username: "lxc", age: 18 });
let [arr, setArr] = useState(["a", "b", "c", "d"]);
function handleAge() {
setObj(
data => {
data.age++;
return { ...data };
})
}
function handlePush() {
var newArr = [...arr];
newArr.push(Math.random());
setArr(newArr);
}
return <div>
<h2>{obj.age}</h2>
{
arr.map((item, index) => (
<p key={index}>{item}</p>
))
}
<button onClick={handleAge}>更改对象年龄</button>
<button onClick={handlePush}>添加数组项</button>
</div>
}
(二)useRef
在组件中获取真实的DOM结构,current代表当前元素,没有绑定时为undefined
import React, { useState, useEffect, useRef } from "react"
export default () => {
let [count, setCount] = useState(10);
let dom = useRef();
function handleAge() {
setCount(count + 1);
}
useEffect(() => {
console.log(dom);
console.log("挂载成功");
})
return (
<div>
<h2 ref={dom}>{count}</h2>
<button onClick={handleAge}>点击年龄</button>
</div>
)
}
(三)useEffect
让组件拥有一些特定的生命周期
参数1:回调
参数2:对比值,只要第二个参数是一个固定值并且不会发生改变,则只会触发componentDidMount
- componentDidMount 挂载成功
模拟:在useEffect的第二个参数中,写一个空数组即可
useEffect(() => {
console.log(dom);
console.log("挂载成功");
},[])
- componentDidUpdate 更新成功
模拟:useEffect的第二个参数不写即可 (eg : 上面的useRef)
- componentWillUnmount 销毁
模拟:在第一个函数中return一个函数,在这个函数中做卸载操作。
- One.js组件,点击按钮时被销毁
import React, { useState, useEffect, useRef } from "react"
export default function One(){
useEffect(() => {
console.log("挂载成功")
return () => {
console.log("组件被销毁");
}
}, [])
return (
<div></div>
)
}
- 在App.js中引入One.js组件
import React, { Component } from 'react'
import One from "./One"
export default class App extends Component {
constructor() {
super();
this.state = {
flag: true,
}
}
render() {
return (
<div>
{this.state.flag ? <One /> : ""}
<button onClick={() => { this.setState({ flag: !this.state.flag }) }}>切换</button>
</div>
)
}
}
(四)useReducer状态管理
可以在函数组件中操作action
参数1:回调(reducer)
参数2:状态(state)
返回值1:state
返回值2:dispatch
let [state,dispatch] = useReducer(reducer,state);
import React, { useReducer } from 'react'
function reducer(state, actions) {
switch (actions.type) {
case "NUM_ADD":
return {
count: ++state.count
}
case "NUM_REDUCE":
return {
count: --state.count
}
}
}
export default function App() {
let [state, dispatch] = useReducer(reducer, { count: 10 });
function handleAdd() {
dispatch({
type: "NUM_ADD"
})
}
function handleReduce() {
dispatch({
type: "NUM_REDUCE"
})
}
return (
<div>
<h2>{state.count}</h2>
<button onClick={handleAdd}>+</button>
<button onClick={handleReduce}>-</button>
</div>
)
}
网友评论