看完这篇,你也能把 React Hooks 玩出花

 

https://juejin.im/post/5d754dbde51d4561cd2466bf

这篇文章中有些案例还是不错,在自定义hook这里写得很好

  useMemo  返回值可为数字,可为组件;

  useCallback 用着对useEffect中相同逻辑的封装,配合Effect使用;

useMemo  返回值可为数字,可为组件

返回值是数字

import React, { useState, useMemo } from 'react';
import { message } from 'antd';

export default function HookDemo() {
  const [count1, changeCount1] = useState(0);
  const [count2, changeCount2] = useState(10);

  const calculateCount = useMemo(() => {
    message.info('重新生成计算结果');
    return count1 * 10;
  }, [count1]);
  return (
    <div>
      {calculateCount}
      <button onClick={() => { changeCount1(count1 + 1); }}>改变count1</button>
      <button onClick={() => { changeCount2(count2 + 1); }}>改变count2</button>
    </div>
  );
}

作者:政采云前端团队
链接:https://juejin.im/post/5d754dbde51d4561cd2466bf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

返回的为组件

import React, { useState, useMemo } from 'react';
import { message } from 'antd';

function Child({ count }) {
  return <p>当前传递的count为:{count}</p>;
}

export default function HookDemo() {
  const [count1, changeCount1] = useState(0);
  const [count2, changeCount2] = useState(10);

  const child = useMemo(() => {
    message.info('重新生成Child组件');
    return <Child count={count1} />;
  }, [count1]);
  return (
    <div>
      {child}
      <button onClick={() => { changeCount1(count1 + 1); }}>改变count1</button>
      <button onClick={() => { changeCount2(count2 + 1); }}>改变count2</button>
    </div>
  );
}

作者:政采云前端团队
链接:https://juejin.im/post/5d754dbde51d4561cd2466bf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

useCallback的这种用法也算新奇,其问如下:

生成 Callback 的钩子。用于对不同 useEffect 中存在的相同逻辑的封装,减少代码冗余,配合 useEffect 使用。

该钩子先看例子会比较好理解一下:

const [count1, changeCount1] = useState(0);
const [count2, changeCount2] = useState(10);

const calculateCount = useCallback(() => {
  if (count1 && count2) {
    return count1 * count2;
  }
  return count1 + count2;
}, [count1, count2])

useEffect(() => {
    const result = calculateCount(count, count2);
    message.info(`执行副作用,最新值为${result}`);
}, [calculateCount])


作者:政采云前端团队
链接:https://juejin.im/post/5d754dbde51d4561cd2466bf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

钩子/最终总结

钩子总结

钩子

用法

作用

useState

const [state, changeState] = useState(initialValue)

用于生成状态以及改变状态的方法

useEffect

useEffect(fn, [...relativeState])

用于生成与状态绑定的副作用

useCallback

useCallback(fn, [...relativeState])

用于生成与状态绑定的回调函数

useMemo

useMemo(fn, [...relativeState])

用于生成与状态绑定的组件/计算结果

useRef

const newRef = useRef(initialValue)

用于 获取节点实例 / 数据保存

从上面的表格中我们可以看出,在官方提供的 Hook 中,除了基本的 useStateuseRef 外,其他钩子都存在第二个参数,第一个方法的执行与第二个参数相互关联。于是我们可以得出一个结论,在使用了 Hook 的函数式组件中,我们在使用副作用/引用子组件时都需要时刻注意对代码进行性能上的优化

最终总结

我在前面的总结里是这么评价 React Hooks 的:

Hooks 组件的目标并不是取代 class component 组件,而是增加函数式组件的使用率,明确通用工具函数与业务工具函数的边界,鼓励开发者将业务通用的逻辑封装成 React Hooks 而不是工具函数


作者:政采云前端团队
链接:https://juejin.im/post/5d754dbde51d4561cd2466bf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

编写自己的钩子

其实从上面讲解的内容来看,钩子并不是什么高深莫测的东西,它只是对我们常用逻辑的一些封装,接下来就会通过具体的代码来教大家写一个自己的钩子。

最基本的钩子

最基本的钩子也就是返回包含了更多逻辑的 State 以及改变 State 方法的钩子。拿计数器来说,其最基本的就是返回当前的数字以及减少/增加/重置等功能,明确完功能后可以开始动手做了。

import React, { useState } from 'react';

// 编写我们自己的hook,名字以use开头
function useCounter(initialValue) {
  // 接受初始化的值生成state
  const [count, changeCount] = useState(initialValue);
  // 声明减少的方法
  const decrease = () => {
    changeCount(count - 1);
  }
  // 声明增加的方法
  const increase = () => {
    changeCount(count + 1);
  }
  // 声明重置计数器方法
  const resetCounter = () => {
    changeCount(0);
  }
  // 将count数字与方法返回回去
  return [count, { decrease, increase, resetCounter }]
}

export default function myHooksView() {
  // 在函数组件中使用我们自己编写的hook生成一个计数器,并拿到所有操作方法的对象
  const [count, controlCount] = useCounter(10);
  return (
  	<div>
    	当前数量:{count}
			<button onClick={controlCount.decrease}>减少</button>
			<button onClick={controlCount.increase}>增加</button>
			<button onClick={controlCount.resetCounter}>重置</button>
    </div>
  )
}
复制代码

在上面的例子中,我们将在 useCounter 这个钩子中创建了一个关联了 initialValue 的状态,并创建减少/增加/重置的方法,最终将其通过 return 返回出去。这样在其他组件需要用到该功能的地方,通过调用该方法拿到其返回值,即可实现对 useCounter 组件封装逻辑的复用。

演示效果如图:

 

counter

 

 

返回 DOM 的钩子

返回 DOM 其实和最基本的 Hook 逻辑是相同的,只是在返回的数据内容上有一些差异,具体还是看代码,以一个 Modal 框为例。

import React, { useState } from 'react';
import { Modal } from 'antd';

function useModal() {
  const [visible, changeVisible] = useState(false);

  const toggleModalVisible = () => {
    changeVisible(!visible);
  };

  return [(
    <Modal
      visible={visible}
      onOk={toggleModalVisible}
      onCancel={toggleModalVisible}
    >
      弹窗内容
  	</Modal>
  ), toggleModalVisible];
}

export default function HookDemo() {
  const [modal, toggleModal] = useModal();
  return (
    <div>
      {modal}
      <button onClick={toggleModal}>打开弹窗</button>
    </div>
  );
}

复制代码

这样我们就实现了一个返回了弹窗内容以及改变弹窗显示状态的 Hook,其实可以封装的内容还有很多很多,可以通过配置项的设置实现更丰富的封装。

演示效果如图:

 

modal

 

 

钩子/最终总结


作者:政采云前端团队
链接:https://juejin.im/post/5d754dbde51d4561cd2466bf
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值