React - Hooks 使用(函数组件中使用 React 特性)
- 一. 为什么要使用 HOOKS?
- 二. HOOKS 概念
- 三. HOOKS 用法
- 1. useState
- 1.1 参数及返回值
- 1.2 setState 两种写法
- 1.3 setState 示例
- 2. useEffect
- 2.1 useEffect 实例
- 3. useRef
- 3.1 useRef 实例
- 四. 一个 Hooks 组件实例
Hook
是React 16.8.0版本增加的新特性/新语法- 可以在函数组件中使用 state 以及其他的 React 特性
一. 为什么要使用 HOOKS?
- React的组件创建方式,一种是类组件,一种是函数组件。
- 函数组件相比较类组件,具有以下特点:
(1)函数组件没有状态
(2)函数组件没有生命周期
(3)函数组件没有this
- 这就说明函数组件,只能做UI展示的功能,涉及到状态的管理与切换,就不得不用类组件或者redux。
- 在这种情况下,如果想使用函数组件编写一个完整的功能,就可以使用
HOOKS
。
二. HOOKS 概念
Hook
是React 16.8.0版本增加的新特性/新语法- 可以在函数组件中使用 state 以及其他的 React 特性
三. HOOKS 用法
- State Hook:
React.useState()
- Effect Hook:
React.useEffect()
- Ref Hook:
React.useRef()
1. useState
使函数组件也可以有
state
状态, 并进行状态数据的读写操作。
import { useState } from "react";
const [state, setState] = useState(initState);
1.1 参数及返回值
initState
: useState 参数
在初始渲染期间,指定state
值在内部作缓存[state, setState]
: useState 返回值,包含两个元素的数组,
第一个参数:为内部当前的state
状态值,
第二个参数:为更新state
状态值的函数
1.2 setState 两种写法
-
第一种写法
setState(newState);
参数为 非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
-
第二种写法
setState(state => { // state : 原本的state值 return newState });
参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值
1.3 setState 示例
const [count, setCount] = useState(0);
setCount(count + 1);
setCount((count) => {
// count : 原本的state值
return count + 1;
});
2. useEffect
在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
可以用来更好的处理副作用,比如 添加订阅、设置定时器、接口请求 以及执行其他包含副作用的操作
import { useEffect } from "react";
useEffect(
() => {
// 在此可以执行任何带副作用操作
return () => { // 在组件卸载前执行
// 在此做一些收尾工作, 比如清除定时器/取消订阅等
};
},
[stateValue],// 如果指定的是[], 回调函数只会在第一次render()后执行
);
可以把 useEffect Hook 看做如下三个函数的组合:
componentDidMount()
componentDidUpdate()
componentWillUnmount()
2.1 useEffect 实例
const [count, setCount] = useState(0);
useEffect(() => {
// 定时器
let timer = setInterval(() => {
setCount((count) => count + 1);
}, 1000);
return () => {
// 清除定时器
clearInterval(timer);
};
}, []);
3. useRef
可以在函数组件中存储/查找组件内的标签或任意其它数据
作用:保存标签对象,功能与React.createRef()
一样
import { useRef } from "react";
const refContainer = useRef(initValue);
3.1 useRef 实例
<input ref={myRef} type="text" />
<button onClick={showInputValue}>提示输入框信息</button>
const myRef = useRef();
function showInputValue() {
console.log(myRef.current.value);
}
四. 一个 Hooks 组件实例
类组件 对比 函数组件
实现 state 状态修改、定时器、输入框信息打印、组件卸载
-
类组件 实现
src/index.js 暴露 root
import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <BrowserRouter> <App /> </BrowserRouter> ); export default root;
import React, { Component } from "react"; import { createRef } from "react"; import root from "../../index";//引入root路径 export default class index extends Component { state = { count: 0, name: "tom", }; myRef = createRef(); componentDidMount() { this.timer = setInterval(() => { this.setState({ count: this.state.count + 1, }); }, 1000); } componentWillUnmount() { clearInterval(this.timer); } increment = () => { this.setState((state) => { return { count: state.count + 1, }; }); }; updateName = () => { this.setState({ name: "小明", }); }; unMount = () => { root.unmount(); }; showInputValue = () => { console.log(this.myRef.current.value); }; render() { return ( <div> <h4>数值为:{this.state.count}</h4> <button onClick={this.increment}>+1</button> <h4>名字:{this.state.name}</h4> <button onClick={this.updateName}>改名</button> <br /> <br /> <button onClick={this.unMount}>卸载组件</button> <br /> <br /> <input ref={this.myRef} type="text" /> <button onClick={this.showInputValue}>打印输入框信息</button> </div> ); } }
-
函数组件 实现
src/index.js 暴露 root
import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <BrowserRouter> <App /> </BrowserRouter> ); export default root;
import { useState, useEffect, useRef } from "react"; import root from "../../index";//引入root路径 function Index() { const [count, setCount] = useState(0); const [name, setName] = useState("tom"); const myRef = useRef(); useEffect(() => { let timer = setInterval(() => { setCount((count) => count + 1); }, 1000); return () => { clearInterval(timer); }; }, []); function increment() { // setCount(count + 1);// 第一种写法 setCount((count) => { return count + 1; }); } function updateName() { setName("小明"); } function unMount() { root.unmount(); } function showInputValue() { console.log(myRef.current.value); } return ( <div> <h4>数值为:{count}</h4> <button onClick={increment}>+1</button> <h4>名字:{name}</h4> <button onClick={updateName}>改名</button> <br /> <br /> <button onClick={unMount}>卸载组件</button> <br /> <br /> <input ref={myRef} type="text" /> <button onClick={showInputValue}>打印输入框信息</button> </div> ); } export default Index;
-
组件实现效果图