React Hooks 快速入门(一)(useState、useEffect)


前言


一、React Hooks是什么?

React Hooks是目前数据React 最火的新特性,改变了原始React继承类组件的方式,改为函数式组件,并且采用预函数的形式管理state,极大提高组件复用效率。

二、前期项目准备

需要注意,初始化create-react-app项目时,项目文件夹名字不能有大写

create-react-app react_hooks_demo //创建项目
cd react_hooks_demo  //cd 到项目目录
yarn start //启动项目

三、React Hooks 编写形式与类继承形式对比

原始类继承式组件写法:创建OriginExample.js

//原始类继承式组件写法
import React, { Component } from 'react';

export default class OriginExample extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0
        }
    }
    //射击事件
    ShootClick = () => {
        this.setState({
            count:this.state.count+1
        })
    }
    render() {
        return (
            <div>
                <h1>原始类继承component写法</h1>
                <p>你已经射击了{this.state.count}次!</p>
                <button onClick={this.ShootClick}>射击</button>
            </div>
        );
    }
}

React Hooks函数式组件写法:创建HooksExample.js

import React, { useState } from 'react';

export default function HooksExample() {
    const [count, setCount] = useState(0); //count 初始值为0
    return (
        <div>
                <h1>React Hooks 写法</h1>
                <p>你已经射击了{count}次!</p>
                <button onClick={()=>{setCount(count+1)}}>射击</button>
        </div>
    )

}

四、useState 的介绍和多状态声明

1.useState 的介绍

useState 是React自带的一个hook函数,作用是声明,读取,修改变量(下面是useState的源码)

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
    /**
     * 返回一个有状态值和一个更新它的函数。
     */

useState这个函数接受一个initialState初始值参数,同时返回一个状态值以及更新此状态值的函数

const [count, setCount] = useState(0); //count 初始值为0

所以上述初始化useState 使用了ES6中数组解构的语法,将状态值以及更新函数解构

1.多状态声明的注意事项

React Hook 不能出现在条件判断语句中,需要保持完全一样的渲染顺序

import React, { useState } from 'react';

export default function HooksExample() {
    const [count, setCount] = useState(0); //count 射击次数初始值为0
    const [bulletCount, setBulletCount] = useState(20); //count 子弹初始值为100
    const ActionClick = () => { 
        setCount(count + 1); 
        setBulletCount(bulletCount - 1) 
    }
    return (
        <div>
            <h1>React Hooks 写法</h1>
            <p>你已经射击了{count}次!</p>
            {
                bulletCount === 0 ? (
                    <p style={{ color: "red" }} >你已经弹尽粮绝了!</p>
                ) : (
                    <p style={{ color: "greenyellow" }} >还有{bulletCount}发子弹!</p>
                )
            }
            <button onClick={ bulletCount>0?ActionClick:alert("你没子弹了!")}>射击</button>
            

        </div>
    )

}


按顺序声明多个状态就可以,如果在React Hook 出现在条件语句中,程序就会报错

五、useEffect 代替常用生命周期函数

1.用Class继承方式使用生命周期函数

OriginExample.js中加入生命周期函数

	componentDidMount(){
        //组件挂载完成
        console.log(`组件挂载完成=>你射击了${this.state.count}次!`)
    }
    componentDidUpdate(){
        //组件更新完成
        console.log(`组件更新完成=>你射击了${this.state.count}次!`)
    }

效果如下:
在这里插入图片描述

2.useEffect 函数代替class中生命周期函数

HooksExample.js中加入useEffect代码

  import React, { useState ,useEffect} from 'react';

export default function HooksExample() {
    const [count, setCount] = useState(0); //count 射击次数初始值为0
    const [bulletCount, setBulletCount] = useState(20); //count 子弹初始值为100
    const ActionClick = () => { 
        setCount(count + 1); 
        setBulletCount(bulletCount - 1) 
    }

    //使用useEffect函数代替生命周期函数
    useEffect(() => {
        console.log(`useEffect=>你射击了${count}次!`)
    })
    
    return (
        <div>
            <h1>React Hooks 写法</h1>
            <p>你已经射击了{count}次!</p>
            {
                bulletCount === 0 ? (
                    <p style={{ color: "red" }} >你已经弹尽粮绝了!</p>
                ) : (
                    <p style={{ color: "greenyellow" }} >还有{bulletCount}发子弹!</p>
                )
            }
            <button onClick={ bulletCount>0?ActionClick:alert("你没子弹了!")}>射击</button>
            

        </div>
    )

}


结果如下:
在这里插入图片描述

六、使用useEffect 实现componentWillUnmount组件卸载函数

代替componentWillUnmount函数功能

学习这个功能需要使用路由来切换页面触发componentWillUnmount组件卸载函数,所以要在项目中添加react-router-dom

npm

npm install react-router-dom

yarn

yarn add react-router-dom

下载完react-router-dom之后在程序引入

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

完整代码:

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

//css 
const routeCssObj = { 
    display: "flex", 
    justifyContent: "space-around", 
    listStyleType: "none", 
    margin: "10% auto" ,
}
const redBgc = { backgroundColor: "#F34725" ,color:"white"}
const blueBgc = { backgroundColor: "#25D0F3" ,color:"white"}


//声明两个组件
function Red() {
    //Red组件内生命周期函数
    useEffect(()=>{
        console.log("我们一起进入了Red组件!!!!!")
        return ()=>{
            console.log("我们离开了Red组件------------------")
        }
    })
    return <h1 style={redBgc}>Red组件</h1>
}
function Blue() {
    //Blue组件内生命周期函数
    useEffect(()=>{
        console.log("我们一起进入了Blue组件!!!!!")
        return ()=>{
            console.log("我们离开了Blue组件------------------")
        }
    })
    return <h1 style={blueBgc}>Blue组件</h1>
}
export default function HooksExample() {
    
    //声明两个组件当作路由组件
    const [routeObj] = useState([
        {
            path: "/red",
            name: "Red组件",
            component: Red
        },
        {
            path: "/blue",
            name: "Blue组件",
            component: Blue
        }
    ])
   
    return (
        <div>
            
            {/* 路由配置,需要学习react路由相关的前置知识 */}

            <Router>
                <ul style={routeCssObj}>
                    {
                        routeObj.map((item, index) => {
                            return <li key={index}><Link to={item.path}>{item.name}</Link></li>
                        })
                    }
                </ul>
                {
                    routeObj.map((item, index) => {
                        return <Route  key={index} path={item.path} component={item.component}></Route>
                    })
                }
            </Router>

        </div>
    )

}


实现效果:
在这里插入图片描述

2.useEffect中第二个参数(两种情况)

  1. 第二个参数为空数组 :[]
    当我们第二个参数传入[]时,表示当组件被销毁时才进行解绑
  2. 第二个参数为状态变量:比如之前声明的count
    这个时候只要count状态发生变化,就会执行解绑函数

总结

学如逆水行舟,不进则退

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

与诸君共勉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值