hook介绍

一.hook(钩子):(按照生命周期和功能进行封装)

优势:逻辑简化.

而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件。

(1)要启用Hooks,所有React软件包都必须为16.8.0或更高版本.

(2)钩子是允许从功能组件(function component)“挂钩”React状态和生命周期功能的功能。钩子在类内部不起作用-它们允许你在没有类的情况下使用React.

(3)React提供了一些像useState这样的内置Hook。你还可以创建自定义Hook以在不同组件之间重用有状态行为.

(4)Hook是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook不能在class组件中使用——这使得你不使用 class也能使用 React。(我们不推荐把你已有的组件全部重写,但是你可以在新组件里开始使用 Hook。)(2020-5新更新解释)

二.hook规则

1.hook是JavaScript函数,但它们强加了两个额外的规则.
(1)只能在顶层调用Hooks。不要在循环,条件或嵌套函数中调用Hook.
(2)仅从React功能组件调用Hooks。不要从常规JavaScript函数中调用Hook.

三.基本hook-useState

1.useState语法:const [state,setState] = useState(initialState);)(里面封装的是state(对象),在用的时候.)

(1)返回一个有状态值,以及一个更新它的函数.

(2)在初始渲染期间,返回的状态(state)与作为第一个参数(initialState)传递的值相同.

(3)该setState功能用于更新状态。它接受一个新的状态值并排队重新呈现组件.

(4)setState(newState);

(5)在随后的重新渲染过程中,返回的第一个值useState将始终是应用更新后的最新状态.

例1:

shook.js:

import React, { useState } from 'react';

export function Shook() {
    const [count, setCount] = useState(0);
    return (
        <div>
            <h2 onClick={() => setCount(count + 1)}>useState的使用</h2>
            <p>你点了{count}次</p>
        </div>
    )
}

 最终效果图:

点击前:

 点击后:

 引用的是Shook函数名:

例2:

shook.js:

import React, { useState } from 'react';

export function Shook() {
    const [a, seta] = useState(0);
    const [count, setCount] = useState(
        { n: 0, stu: [{ id: 1, names: "aaa" }, { id: 2, names: "bbb" }, { id: 3, names: "ccc" }, { id: 4, names: "ddd" }] }
    );
    return (
        <div>
            <h2 onClick={() => seta(a + 1)}>useState的使用</h2>
            <p>你点了{a}</p>
            <ul>
                {count.stu.map(v => <li key={v.id}>{v.names}</li>)}
            </ul>
        </div>
    )
}

 最终效果图:

 点击前:

点击后:

 例3:

shook.js:

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

export function Shook() {
    const [count, setCount] = useState(
        { n: 0, stu: [{ id: 1, names: "aaa" }, { id: 2, names: "bbb" }, { id: 3, names: "ccc" }, { id: 4, names: "ddd" }] }
    );
    useEffect(() => {
        count.n += 1;
        setCount({ stu: count.stu, n: count.n });
    }, [])
    return (
        <div>
            <h2>useState的使用</h2>
            <p>你点了{count.n}</p>
            <ul>
                {count.stu.map(v => <li key={v.id}>{v.names}</li>)}
            </ul>
        </div>
    )
}

 最终效果图:

基本hook-useEffect

1.useEffect语法:useEffect(didUpdate);

(1)接受包含命令式(可能是有效代码)的函数.

(2)函数组件(称为react的呈现阶段)的主体中不允许出现Mutations,subscriptions, timers, logging和其他副作用。这样做将导致混淆错误和不一致的用户界面.

(3)从React组件执行数据提取,订阅或手动更改DOM。我们将这些操作称为“副作用”(或简称为“效果”),因为它们会影响其他组件,并且在渲染过程中无法完成.

(4)Efifect Hook中的useEffect增加了在功能组件执行副作用的功能。它与React类中的componentDidMount,componentDidUpdate和componentWillUnmount具有相同的用途,但统一为单个API.

效果

注意

每次渲染后都执行清理或者执行effect

这可能会导致性能问题,比如两次渲染的数据完全一样

只运行一次的effect(仅在组件挂载和卸载时执行)

这就告诉React你的 effect不依赖于props或 state中的任何值,所以它永远都不需要重复执行

React将对前一次渲染的count和后一次渲染的count进行比较。若相等React 会跳过这个 effect 

实现了性能的优化

例:

shook.js:

import React, { useState, useEffect } from 'react';
export function Teachers() {
    const [tes, setTes] = useState({ teachers: [], loads: false });
    useEffect(() => { getTeacher(); }, tes.teachers)
    function getTeacher(){
        let ts = fetch("http://www.qhdlink-student.top/student/coach.php", {
            method: "POST",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded"
            },
            body: 'username=ljj&userpwd=12345678&userclass=53&type=2'
        });
        ts.then(res => res.json()).then(json => {
            for (let v in json) {
                tes.teachers.push(json[v]);
            }
            setTes({ teachers: tes.teachers, loads: true })
            // tes.loads = ture;
            // setTes({ teachers: tes.teachers, loads: tes.loads })
        })
    }
    return (
        <div>
            <h2>师资力量</h2>
            {!tes.loads ? <h3>加载中...</h3> : tes.teachers.map(v => <p key={v.id_coach}>{v.name_coach}</p>)}
        </div>
    )
}

例:

shook.js:

import React, { useState, useEffect,useReducer } from 'react';
const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

export function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

 

 效果图:

  • 28
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值