我的编程空间,编程开发者的网络收藏夹
学习永远不晚

编写简洁React组件的小技巧

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

编写简洁React组件的小技巧

本文源于翻译文章 Simple tips for writing clean React components, 原文作者 Iskander Samatov

在这篇文章中,我们会回顾一些简单的技巧,它们将帮助我们编写更简洁的 React 组件,并且更好地扩展我们的项目。

避免使用扩展操作符传递 props

首先,让我们从一个应该避免的反模式开始。除非有明确的理由这样做,否则应该避免在组件树中使用扩展操作符传递props,比如:{ ...props }。

通过这种方式传递 props 确实可以更快的编写组件。但这也使得我们很难去定位代码中的 bug。会使我们对编写的组件失去信心,会使得我们重构组件变得更加困难,而且可能会导致出现很难排查的 bug。

将函数参数封装成一个对象

如果函数接收多个参数,最好将它们封装成一个对象。举个例子:


export const sampleFunction = ({ param1, param2, param3 }) => {
  console.log({ param1, param2, param3 });
}

以这种方式编写函数签名有几个显著的优点:

  1. 你不用再担心参数传递的顺序。我曾犯过几次因函数传参顺序问题而产生了 bug 的错误。
  2. 对于配置了智能提示的编辑器(现在的大多数都有),可以很好地完成函数参数的自动填充。

对于事件处理函数,将该处理函数作为函数的返回值

如果你熟悉函数式编程,这种编程技术类似于函数柯里化,因为已经提前设置了一些参数。

我们来看看这个例子:


import React from 'react'

export default function SampleComponent({ onValueChange }) {

  const handleChange = (key) => {
    return (e) => onValueChange(key, e.target.value)
  }

  return (
    <form>
      <input onChange={handleChange('name')} />
      <input onChange={handleChange('email')} />
      <input onChange={handleChange('phone')} />
    </form>
  )
}

如您所见,以这种方式编写处理程序函数,可以使组件树保持简洁。

组件渲染使用 map 而非 if/else

当你需要基于自定义逻辑呈现不同的元素时,我建议使用使用 map 而非 if/else 语句。

下面是一个使用if/else的示例:


import React from 'react'

const Student = ({ name }) => <p>Student name: {name}</p>
const Teacher = ({ name }) => <p>Teacher name: {name}</p>
const Guardian = ({ name }) => <p>Guardian name: {name}</p>

export default function SampleComponent({ user }) {
  let Component = Student;
  if (user.type === 'teacher') {
    Component = Teacher
  } else if (user.type === 'guardian') {
    Component = Guardian
  }

  return (
    <div>
      <Component name={user.name} />
    </div>
  )
}

下面是一个使用map的示例:


import React from 'react'

const Student = ({ name }) => <p>Student name: {name}</p>
const Teacher = ({ name }) => <p>Teacher name: {name}</p>
const Guardian = ({ name }) => <p>Guardian name: {name}</p>

const COMPONENT_MAP = {
  student: Student,
  teacher: Teacher,
  guardian: Guardian
}

export default function SampleComponent({ user }) {
  const Component = COMPONENT_MAP[user.type]

  return (
    <div>
      <Component name={user.name} />
    </div>
  )
}

使用这个简单的小策略,可以使你的组件变得更具有可读性,更容易理解。而且它还使逻辑扩展变得更简单。

Hook组件

只要不滥用,这个模式是很有用的。

你可能会发现自己在应用中使用了很多组件。如果它们需要一个状态来发挥作用,你可以将他们封装为一个 hook 提供该状态。这些组件的一些好例子是弹出框、toast 通知或简单的 modal 对话框。例如,下面是一个用于简单确认对话框的 hook 组件:


import React, { useCallback, useState } from 'react';
import ConfirmationDialog from 'components/global/ConfirmationDialog';

export default function useConfirmationDialog({
  headerText,
  bodyText,
  confirmationButtonText,
  onConfirmClick,
}) {
  const [isOpen, setIsOpen] = useState(false);

  const onOpen = () => {
    setIsOpen(true);
  };

  const Dialog = useCallback(
    () => (
      <ConfirmationDialog
        headerText={headerText}
        bodyText={bodyText}
        isOpen={isOpen}
        onConfirmClick={onConfirmClick}
        onCancelClick={() => setIsOpen(false)}
        confirmationButtonText={confirmationButtonText}
      />
    ),
    [isOpen]
  );

  return {
    Dialog,
    onOpen,
  };
}

你可以像这样使用 hook 组件:


import React from "react";
import { useConfirmationDialog } from './useConfirmationDialog'

function Client() {
  const { Dialog, onOpen } = useConfirmationDialog({
    headerText: "Delete this record?",
    bodyText:
      "Are you sure you want delete this record? This cannot be undone.",
    confirmationButtonText: "Delete",
    onConfirmClick: handleDeleteConfirm,
  });

  function handleDeleteConfirm() {
    //TODO: delete
  }

  const handleDeleteClick = () => {
    onOpen();
  };

  return (
    <div>
      <Dialog />
      <button onClick={handleDeleteClick} />
    </div>
  );
}

export default Client;

以这种方式提取组件可以避免编写大量状态管理的样板代码。如果你想了解更多 React hooks,请查看 我的帖子。

组件拆分

下面三个技巧是关于如何巧妙地拆分组件。根据我的经验,保持组件的简洁是保持项目可管理的最佳方法。

使用包装器

如果你正在努力寻找一种方法来拆分复杂组件,看看你的组件中每个元素所提供的功能。有些元素提供了独特的功能,比如拖拽功能。

下面是一个使用react-beautiful-dnd实现拖拽的组件示例:


import React from 'react'
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
export default function DraggableSample() {
  function handleDragStart(result) { 
    console.log({ result });
  }
  function handleDragUpdate({ destination }) { 
    console.log({ destination });
  }
  const handleDragEnd = ({ source, destination }) => { 
    console.log({ source, destination });
  };
  return (
    <div>
      <DragDropContext
        onDragEnd={handleDragEnd}
        onDragStart={handleDragStart}
        onDragUpdate={handleDragUpdate}
      >
        <Droppable 
          droppableId="droppable"
          direction="horizontal"
        >
          {(provided) => (
            <div {...provided.droppableProps} ref={provided.innerRef}> 
              {columns.map((column, index) => {
                return (
                  <ColumnComponent
                    key={index}
                    column={column}
                  />
                );
              })}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </div>
  )
}

现在,看一下在我们将所有拖拽逻辑移到包装器之后的组件:


import React from 'react'
export default function DraggableSample() {
  return (
    <div>
      <DragWrapper> 
      {columns.map((column, index) => { 
        return (
          <ColumnComponent key={index} column={column}/>
        );
      })}
      </DragWrapper>
    </div>
  )
}

下面是包装器的代码:


import React from 'react'
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
export default function DragWrapper({children}) {
  function handleDragStart(result) { 
    console.log({ result });
  }
  function handleDragUpdate({ destination }) { 
    console.log({ destination });
  }
  const handleDragEnd = ({ source, destination }) => { 
    console.log({ source, destination });
  };
  return (
    <DragDropContext 
      onDragEnd={handleDragEnd}
      onDragStart={handleDragStart} 
      onDragUpdate={handleDragUpdate}
    >
      <Droppable droppableId="droppable" direction="horizontal"> 
        {(provided) => (
          <div {...provided.droppableProps}  ref={provided.innerRef}> 
            {children}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  )
}

因此,可以更直观地看到组件在更高层次上的功能。所有用于拖拽的功能都在包装器中,使得代码更容易理解。

关注点分离

这是我最喜欢的拆分较大组件的方法。

从 React 角度出发,关注点的分离意味着分离组件中负责获取和改变数据的部分和纯粹负责显示元素的部分。

这种分离关注点的方法是引入 hooks 的主要原因。你可以用自定义 hook 封装所有方法或全局状态连接的逻辑。

例如,让我们看看如下组件:


import React from 'react'
import { someAPICall } from './API' 
import ItemDisplay from './ItemDisplay'
export default function SampleComponent() { 
  const [data, setData] = useState([])
  useEffect(() => { 
    someAPICall().then((result) => { setData(result)})
  }, [])
  function handleDelete() { console.log('Delete!'); }
  function handleAdd() { console.log('Add!'); }
  const handleEdit = () => { console.log('Edit!'); };
  return (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)} 
      </div>
      <div>
        <button onClick={handleDelete} /> 
        <button onClick={handleAdd} /> 
        <button onClick={handleEdit} /> 
      </div>
    </div>
  )
}

下面是它的重构版本,使用自定义hook拆分后的代码:


import React from 'react'
import ItemDisplay from './ItemDisplay'
export default function SampleComponent() {
  const { data, handleDelete, handleEdit, handleAdd } = useCustomHook()
  return (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)} 
      </div>
      <div>
        <button onClick={handleDelete} /> 
        <button onClick={handleAdd} /> 
        <button onClick={handleEdit} /> 
      </div>
    </div>
  )
}

这是该 hook 本身的代码:


import { someAPICall } from './API'
export const useCustomHook = () => { 
  const [data, setData] = useState([])
  useEffect(() => { 
    someAPICall().then((result) => { setData(result)})
  }, [])
  function handleDelete() { console.log('Delete!'); }
  function handleAdd() { console.log('Add!'); }
  const handleEdit = () => { console.log('Edit!'); };
  return { handleEdit, handleAdd, handleDelete, data }
}

每个组件封装为一个单独的文件

通常大家会这样写代码:


import React from 'react'
export default function SampleComponent({ data }) {
  const ItemDisplay = ({ name, date }) => ( 
    <div>
      <h3>{name}</h3>
      <p>{date}</p>
    </div> 
  )
  return (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)}
      </div>
    </div> 
  )
}

虽然用这种方式编写 React 组件没有什么大问题,但这并不是一个好的做法。将 ItemDisplay 组件移动到一个单独的文件可以使你的组件松散耦合,易于扩展。

在大多数情况下,要编写干净整洁的代码,需要注意并花时间遵循好的模式和避免反模式。因此,如果你花时间遵循这些模式,它有助于你编写整洁的 React 组件。我发现这些模式在我的项目中非常有用,希望你也这么做!

以上就是编写简洁React组件的小技巧的详细内容,更多关于编写React组件的技巧的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

编写简洁React组件的小技巧

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

10 个编写更简洁React代码的实用小技巧

本篇文章给大家整理分享 10 个编写更简洁 React 代码的实用小技巧,希望对大家有所帮助!
2023-05-14

编写更简洁React代码的技巧有哪些

这篇文章主要介绍“编写更简洁React代码的技巧有哪些”,在日常操作中,相信很多人在编写更简洁React代码的技巧有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”编写更简洁React代码的技巧有哪些”的疑
2023-07-04

JavaScript代码优雅,简洁的编写技巧总结

专业开发人员将为未来的自己和“其他人”编写代码,而不仅仅只编写当前能工作就行的代码。在此基础上,简洁代码可以定义为自解释的、易于人理解的、易于更改或扩展的代码。以下列表一些好编写方式,仅供参考
2022-11-13

编写更简洁Python代码的技巧有哪些

这篇文章主要介绍“编写更简洁Python代码的技巧有哪些”,在日常操作中,相信很多人在编写更简洁Python代码的技巧有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”编写更简洁Python代码的技巧有哪些
2023-06-16

JavaScript Jest 忍者技巧:编写简洁且高效的测试

探索 JavaScript Jest 忍者技巧,提升测试的简洁性和效率。从定制断言到节省时间的技巧,本文将指导您掌握 Jest 的强大功能,编写高效且易维护的测试代码。
JavaScript Jest 忍者技巧:编写简洁且高效的测试
2024-02-17

写简洁java代码的技巧有哪些

小编给大家分享一下写简洁java代码的技巧有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 定义配置文件信息有时候我们为了统一管理会把一些变量放到 yml
2023-06-29

有哪些python中for循环更简洁的小技巧

这篇文章主要介绍“有哪些python中for循环更简洁的小技巧”,在日常操作中,相信很多人在有哪些python中for循环更简洁的小技巧问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”有哪些python中for
2023-06-16

VUE Mixins 技巧大揭秘:让组件复用与代码简洁触手可及

Vue Mixins 是一个强大的工具,可以帮助您在 Vue.js 组件之间共享数据、方法和行为。通过使用 Mixins,您可以轻松地创建可重用的组件,从而提高代码的简洁性和可维护性。
VUE Mixins 技巧大揭秘:让组件复用与代码简洁触手可及
2024-02-13

Xcode中代码注释编写的一些小技巧

目录前言Objective-C的代码注释Swift的代码注释Objective-C和Swift的注释风格现在已经统一快速修改注释参考文档总结前言码农总是在搬砖,日复一日,年复一年,有的时候都会麻木。 代码大家都会写,但是把注释写好却是一个技
2022-05-31

基于Java编写一个简单的风控组件

这篇文章主要为大家详细介绍了如何基于Java编写一个简单的风控组件,文中的示例代码讲解详细,对我们学习Java有一定的帮助,需要的可以参考一下
2022-12-31

iOS组件依赖避免冲突的小技巧分享

问题缘由本文以 YBImageBrowser[1] 组件举例。 YBImageBrowser 依赖了 SDWebImage,在使用 CocoaPods 集成到项目中时,可能会出现一些依赖冲突的问题,最近社区提了多个 Issues 并且在 I
2022-05-27

怎么使用Java编写一个简单的风控组件

这篇文章主要讲解了“怎么使用Java编写一个简单的风控组件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Java编写一个简单的风控组件”吧!一、背景1.为什么要做风控这不得拜产品大佬
2023-07-04

编程热搜

目录