React Hook笔记(一)

一、useState

声明state变量。React在重复渲染时记住当前的值,并提供最新的值给函数。可以通过setXxx来更新当前的Xxx

例:const [count, setCount] = useState(0);

此处的count是变量名,存储数值;setCount是一个函数,通过它更新count的值。当传递一个新的值给setCount,React会重新渲染组件。

二、useEffect

在函数组件中执行副作用操作。有两种常见的副作用操作:需要清除的和不需要清除的。

副作用:数据获取、设置订阅、手动更改React组件中的DOM。

useEffect会在第一次渲染之后每次更新之后都会执行,通过给useEffect传入第二个参数,它是一个数组,仅在数组内数据变化时才会出发副作用useEffect的回调函数执行。如果传入一个空数组,则只会在组件渲染时执行一次。

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新

(一)、无需清除的effect

无需清除的意思是:执行完某些操作后,就可以忽略它们了。

只是想在React更新Dom之后运行一些额外的代码,比如:发送网络请求、手动变更DOM、记录日志等

useEffect(() => {
    document.title = `You clicked ${count} times`;
});

(二)、需要清除的effect

需要清除的意思是:执行完副作用后要清除,要防止引起内存泄漏。

例如订阅外部数据源

通过返回一个函数,React会在组件卸载时执行清除操作。

useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

每个effect都可以返回一个清除函数(return)

三、自定义Hook

案例:多个组件共用一个请求,比如:请求用户列表,就可以考虑把请求抽离成一个自定义Hook,方便在多个地方调用。

步骤;

1、新建useGetUser.js(名字根据实际命名,但是必须是use开头);

import React, { useState, useEffect } from 'react';
// 引入接口
import { getUserList } from './commonApi';

// props:调用时传入的参数
const UseGetUser = (props) => {
  const [testList, setTestList] = useState([]);
  
  useEffect(() => {
    getUserList(props)
      .then(res => {
        let data = [];
        if (res.status === 200) {
          if (res.data.code === 200) {
            let result = res.data.data;
            for (let item of result) {
              data.push({ ...item, key: item.id });
            }
            // 设置数值
            setTestList(data);
          } else {
            message.destroy();
            message.error(res.data.message);
          }
        } else {
          message.destroy();
          message.error('网络错误!');
        }
      })
      .catch(err => {
        console.log(err);
      })

  }, []);
  
  // 把数据return出去
  return testList;
}

export default UseGetUser;

2、使用自定义Hook

import React from 'react'
// 引入自定义Hook
import useGetUser from '../useGetUser';

function App() {
  // 使用自定义Hook
  const useProjectList = useGetUser({media: 'tt'});
  return (
    <div className="App">
      {
        useProjectList.map((item, index) => <span key={index}>{item}</span>)
      }
    </div>
  )
}


export default App

参考来源:

1、《自定义 Hook》

2、《从一个数据请求,入门React Hooks》

四、useCallback

useMemo功能类似(官方文档提示:可以把useMemo作为性能优化的手段,但不要把它当做语义上的保证,将来可能会被遗忘。)

useCallback(fn, deps) 相当于 useMemo(( )=> fn, deps)

解决组件间的propsstate变化时重复渲染的问题。

案例:父组件渲染时导致子组件也被渲染。

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

function Child({ test, onFatherClick }) {
  useEffect(() => {
    onFatherClick()
  }, [onFatherClick])

  const onClickSon = () => {
    onFatherClick()
  }
  return <div onClick={onClickSon}>{test}</div>
}


function Parent() {
  const [count, setCount] = useState(0)
  const increment = () => setCount(count + 1)

  const [test, setTest] = useState('我从父组件来');

  const onFatherClick = () => {
    console.log('我被渲染了没');
  };

  return (
    <div>
      <button onClick={increment}>我是父组件,我点击了:{count}</button>
      <Child
        test={test}
        onFatherClick={onFatherClick}
      />
    </div>
  );
}

export default Parent;

使用前
可以明显的看出,除了第一次渲染时,在之后的每一次点击时,子组件都会被渲染。这时候可以使用useCallback。

  const onFatherClick = useCallback(() => {
    console.log('我被渲染了没');
  }, []);

使用后

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值