组件间数据更新,可以不写 callback 吗?【玩转 React Hooks】

举报
叶一一 发表于 2023/12/25 09:44:29 2023/12/25
【摘要】 顺手就是一套 callback业务场景在最新一期的需求中,我需要在所有的购买入口,添加"阅读购买须知"的模块。"阅读购买须知"的模块主要包括两部分内容:购买须知按钮和提示文案。提交购买时,也需要增加对应的校验:是否已经进行了阅读操作。如果未操作,给出提示且不能进行下一步操作;如果已操作,可以继续下一步操作。UI 展示效果组件化设计按照代码复用的设计理念,我将"购买须知"模块进行了组件化设计。...

顺手就是一套 callback

业务场景

在最新一期的需求中,我需要在所有的购买入口,添加"阅读购买须知"的模块。

"阅读购买须知"的模块主要包括两部分内容:购买须知按钮和提示文案。

提交购买时,也需要增加对应的校验:是否已经进行了阅读操作。

  • 如果未操作,给出提示且不能进行下一步操作;
  • 如果已操作,可以继续下一步操作。

UI 展示效果

组件化设计

按照代码复用的设计理念,我将"购买须知"模块进行了组件化设计。

下单操作,需要获取"购买须知"组件返回的"阅读状态"的值,于是我顺手写了一个 callback 函数,返回最新的"阅读状态"的值。

"购买须知"组件

这个组件主要包括两个部分:

1、"购买须知"按钮,同时需要在按钮右侧展示提示文字,提示文字根据"阅读状态"不同,展示内容也不同:

  • 未操作时,提示"请单击购买须知";
  • 已操作时,提示"可继续下一步操作"。

2、"购买须知"展示弹窗,展示具体的内容。弹窗有取消和确定两个操作,这两个操作会为"阅读状态"设置不同的值:

  • 确定操作,将"阅读状态"的值设置为1-已操作;
  • 取消操作,将"阅读状态"的值设置为2-未操作。
/**
 * @description 购买须知
 */
import React, { useState } from 'react';
import { Button } from 'antd';

const PurchaseNotes = props => {
  const { callback } = props;
  const [visible, setVisible] = useState(false);
  const [tip, setTip] = useState({});

  /**
   * 根据阅读状态获取展示文字
   * @param {number} status 阅读状态 1-通过 2-不通过
   */
  const getShowTip = status => {
    let healthInformStatusObjAll = {
      1: {
        text: '可继续下一步操作',
        className: 'node-block',
      },
      2: {
        text: '请单击购买须知',
        className: 'node-red',
      },
    };
    let show = healthInformStatusObjAll[status] || {};
    return show;
  };

  /**
   * 公共处理方法
   */
  const commonStatusHandle = status => {
    callback && callback(status);
    const tipObj = getShowTip(status);
    setTip(tipObj);
  };

  /**
   * 操作-关闭
   */
  const cancel = () => {
    setVisible(false);
    commonStatusHandle(2);
  };

  /**
   * 操作-确定
   */
  const ok = () => {
    setVisible(false);
    commonStatusHandle(1);
  };

  return (
    <div>
    <div className={`node ${tip.className}`}>
  <Button
className="mr20"
onClick={() => {
  setVisible(true);
}}
  >
  购买须知
  </Button>
{tip.text ? <div>{tip.text}</div> : null}
  </div>
  <Modal title="购买须知" visible={visible} onOk={ok} onCancel={cancel}>
  <div className="text-left">这是购买须知的内容</div>
  </Modal>
  </div>
 );
};

export default PurchaseNotes;

页面引入组件

1、在购买页面引入组件,并通过 callback 函数设置"阅读状态"值。并在提交操作中加入校验。

/**
 * @description Demo
 */
import React, { useState } from 'react';
import { Button, message } from 'antd';
import PurchaseNotes from './PurchaseNotes';

const Demo = () => {
  const [status, setStatus] = useState(null);

  /**
   * 购买须知回调函数
   */
  const notesCallback = status => {
    setStatus(status);
  };

  /**
   * 提交操作
   */
  const submit = () => {
    // 提交前的校验
    if (status !== 1) {
      return message.error('请单击购买须知');
    }
  };

  return (
    <div>
    <PurchaseNotes callback={notesCallback} />
    <Button type="primary" onClick={submit}>
    提交
    </Button>
    </div>
  );
};

export default Demo;

2、未操作"购买须知"时的展示效果

3、已操作"购买须知"时的展示效果

直接将 setStatus 作为 prop

使用 callback 的目的也是拿到 PurchaseNotes 组件中 status 的值,然后在页面中进行赋值操作。

那直接将 setStatus 作为 prop 传递到 PurchaseNotes 组件中岂不省去了"回调赋值"这一步。

页面传值

将 setStatus 赋值函数 作为 prop 传递到子组件 PurchaseNotes中。

const [status, setStatus] = useState(2);
......
<PurchaseNotes setStatus={setStatus} />

组件赋值

直接使用 setStatus 进行赋值操作。

const { setStatus } = props;
......
/**
 * 公共处理方法
 */
const commonStatusHandle = status => {
  setStatus && setStatus(status);
  ......
};

这样一来,就省了一步"回调赋值"的操作。

总结

虽说这里只是做了简单的一小步改变,但是如果重复的地方多,也能节省了一大波的重复代码。

偶尔,这类"小技巧"容易被开发者忽略,我也是因为"每个页面都得写一遍 callback"枯燥,才想办法找替代方案。

小技巧,大改观。—— 叶一一

显然,成果就是亮点。


作者介绍

非职业「传道授业解惑」的开发者叶一一。

《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。

如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。