HOOK 初使用

HOOK:是一个特殊的函数组件,可以在函数组件内使用生命周期函数和state等特性的函数

useEffect()函数

 useEffect(() => {    
 	ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    
 	//相当于componentWillUnmount()函数
 	return () => {      
 		ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);   
  	};  
  });

在react组件中执行数据获取、订阅或者手动修改DOM,统称为“副作用“。useEffect就是给组件操作副作用的能力。它将componentDidMount、componentDidUpdate 和 componentWillUnmount合并在一起,成为一个api。

无需清除的effect

无需清除的操作:请求数据、手动改变DOM、记录日志等

function Example() {
  const [count, setCount] = useState(0);

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

默认情况下,effect会在每次渲染之后调用,包括第一次调用。

需要清除的effect

如果你的 effect 返回一个函数,React 将会在执行清除操作时调用它:

useEffect(() => {   
  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);    
 	 return function cleanup() {      
  		ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);   
   }; 
    });

useState()函数

const [count, setCount] = useState(0);
//数组解构,useState返回一个数组

与class组件的区别:更新state变量,旧的state变量不会消失,新的state会替换它。

HOOK规则

1.只在最顶层使用HOOK
不要在循环、条件或者嵌套函数中使用HOOK,确保总是在你的react函数的最顶层调用他们。
2.只在react函数中使用HOOK,不要在普通函数中使用HOOK

function Form() {
  // 1. Use the name state variable
  const [name, setName] = useState('Mary');

  // 2. Use an effect for persisting the form
  useEffect(function persistForm() {
    localStorage.setItem('formData', name);
  });

  // 3. Use the surname state variable
  const [surname, setSurname] = useState('Poppins');

  // 4. Use an effect for updating the title
  useEffect(function updateTitle() {
    document.title = name + ' ' + surname;
  });

  // ...
}
// ------------
// 首次渲染
// ------------
useState('Mary')           // 1. 使用 'Mary' 初始化变量名为 name 的 state
useEffect(persistForm)     // 2. 添加 effect 以保存 form 操作
useState('Poppins')        // 3. 使用 'Poppins' 初始化变量名为 surname 的 state
useEffect(updateTitle)     // 4. 添加 effect 以更新标题

// -------------
// 二次渲染
// -------------
useState('Mary')           // 1. 读取变量名为 name 的 state(参数被忽略)
useEffect(persistForm)     // 2. 替换保存 form 的 effect
useState('Poppins')        // 3. 读取变量名为 surname 的 state(参数被忽略)
useEffect(updateTitle)     // 4. 替换更新标题的 effect

// ...

当把HOOK操作都放在最顶层时,react是通过HOOK每次的调用顺序来对应state和effect的操作的。只要HOOK的调用顺序在多次渲染的时候能够保持一致,react就能正确的将内部state和对应的HOOK进行关联。

如果将HOOK放在if语句中

 if (name !== '') {
    useEffect(function persistForm() {
      localStorage.setItem('formData', name);
    });
  }

当if操作不执行时,渲染时跳过这个HOOK操作,就会使得HOOK的调用顺序发生变化,得到错误的结果。

自定义HOOK

REACT CLASS 无法将逻辑在组件中共享,HOOK解决了这个问题。HOOK令组件脱离UI,只将逻辑封装起来。

关于 eslint 和 useEffect 之间的错误提示:
React Hook useEffect has a missing dependency: ‘getFormData’. Either include it or remove the dependency array.
代码:

useEffect(() => {
    getFormData()
  }, [])

useEffect 和 useMemo 之间的区别

简单点说:useEffect是在render渲染之后才运行,useMemo是在render渲染之前执行的。
当Button
父组件:

function App() {
  const [name, setName] = useState('名称')
  const [content,setContent] = useState('内容')
  return (
      <>
        <button onClick={() => setName(new Date().getTime())}>name</button>
        <button onClick={() => setContent(new Date().getTime())}>content</button>
        <Button name={name}>{content}</Button>
      </>
  )
}

子组件

function Button({ name, children }) {
  function changeName(name) {
    console.log('11')
    return name + '改变name的方法'
  }

  const otherName =  changeName(name)
  return (
      <>
        <div>{otherName}</div>
        <div>{children}</div>
      </>

  )
}

当父组件中,点击改变name和改变content时,子组件都会重新渲染,执行changeName函数。我们希望,当改变content时,不执行changeName函数。
用useMemo实现:

function Button({ name, children }) {
  function changeName(name) {
    console.log('11')
    return name + '改变name的方法'
  }

const otherName =  useMemo(()=>changeName(name),[name])
  return (
      <>
        <div>{otherName}</div>
        <div>{children}</div>
      </>

  )
}

export default Button

当父组件的name放生变化时,才会执行changeName函数,改变content时,不会调用。
注:useMemo是在render页面渲染之前执行的,所以是在页面重新渲染otherName之前,就计算otherName的值,避免二次渲染,达到了性能优化的目的。
useEffect是在render渲染之后执行的。在name发生变化时,先render渲染页面,后执行useEffect,改变otherName之后,又重新渲染页面。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值