react项目中的参数解构_重构复杂的React组件:编写高效且可读组件的5个最佳实践...

1335815e4886479aa5889e2a694cd64b

随着 React.js 的不断进化,现在的它已经成为 Web 组件中最受欢迎的视图库之一。但是你手中的它,是否真的能够正常工作呢?本文将主要描述 5 个关于React 组件的最佳实践,希望对正在关注 React 组件的你有所帮助。

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。

问 题

React.js 已成为 Web 组件中最受欢迎的视图库。一路进化下来,它发展出了众多特性,如今已成为创建优秀的 Web 应用程序的一套完整工具。

它的社区经历了爆发式增长,尤其在过去的 2-3 年中,网络上出现了成千上万有关这项技术的教程。

因此,每位初学者在开始学习 React 时都应该做一件事情,那就是阅读其文档或教程进而创建他们的第一个组件,就像我在 Codeworks 上开始我的学习旅途一样:

https://codeworks.me/?utm_source=medium&utm_medium=organic&utm_campaign=marco_ghiani_hackernoon_how_to_write_clean_react_components

但我的问题是:你能肯定你的 React 组件遵循了最佳实践吗?简单来说,它们是不是正常工作呢?

脏组件长什么样

为了更好地说明我的观点,让我们来看看下面的 React 组件:

import React from 'react';import './Listcomponent.css';class Listcomponent extends React.Component { constructor(props) { super(props); this.state = { lastClickedButton: '' }; } render() { return ( 
The last clicked button is {this.state.lastClickedButton} { this.setState({ lastClickedButton: 'Create' }); this.props.createSomething(); }} className="my-button"> Create { this.setState({ lastClickedButton: 'Read' }); this.props.readSomething(); }} className="my-button"> Read { this.setState({ lastClickedButton: 'Update' }); this.props.updateSomething(); }} className="my-button"> Update { this.setState({ lastClickedButton: 'Destroy' }); this.props.destroySomething(); }} className="my-button"> Destroy
); }}

一个肮脏的 React 组件

这是一个完全正常工作的 React 组件,可以在整个应用程序中多次使用。它渲染了一个按钮列表,这些按钮会触发某个事件,组件还会显示最近被点击的是哪个按钮。总之很简单。

你可能会想:“好吧……如果能用,那就没什么问题!”

但如果有人告诉你,现在这个用 62 行代码写成的组件其实用少得多的代码也能做出来呢?所以我们开始做扫除吧!

1. 优先使用 React Hooks 实现函数组件

随着 React 16.8 引入 Hooks,我们就可以在类声明中使用函数组件来构成有状态组件(如果我们需要处理任何逻辑)了。

在本文中,我们不会深入讨论类与函数组件或 React Hooks。但在 React 社区中众所周知的是,最好优先创建函数组件,尤其是现在我们有了 Hooks 这么好用的工具。

Hooks 允许你复用状态逻辑,而无需更改组件层次结构。

接下来让我们看一下第一次重构后组件的样子:

import React, { useState } from 'react';import './ListComponent.css';const ListComponent = props => { const [lastClickedButton, setLastClickedButton] = useState(''); return ( 
The last clicked button is {lastClickedButton} { setLastClickedButton('Create'); props.createSomething(); }} className="my-button"> Create { setLastClickedButton('Read'); props.ReadSomething(); }} className="my-button"> Read { setLastClickedButton('Update'); props.updateSomething(); }} className="my-button"> Update { setLastClickedButton('Destroy'); props.DestroySomething(); }} className="my-button"> Destroy
);};

用 React Hooks 重构成函数组件很好,我们的组件已经短一些了,我们还删除了 语法,但仍然需要做许多优化工作。

2. 利用好它!

我们可以在这个组件中找到什么模式吗?看一下代码,似乎我们每次都渲染一个相似的 button 元素,每个元素都接受一些相似的 props,所以非常适合把这个长组件切成许多小块。

因此我们可以进一步重构这个组件,创建另一个小的函数组件来渲染按钮,并传递一些属性,如 action、setClicked 和 title:

import React, { useState } from 'react';import './ListComponent.css';const ListItemComponent = props => { return { 
{ props.setClicked(props.title); props.action(); }} className="my-button"> {props.title} );};const ListComponent = props => { const [lastClickedButton, setLastClickedButton] = useState(''); return
The last clicked button is {lastClickedButton}
);};

好的,我们的组件开始变好看了,但是仍有改进的余地,让我们继续吧!

3. 正确命名和 props 解构

setLastClickedButton 是 setter 函数的描述性名称,但我们需要保持代码的可读性和简洁,因此请务必起一个最短、最精炼的名字,这是很重要的。我们将其重命名为 setClicked。

同样,只要有可能,从 props 对象解构出来你需要的东西就可以避免多次重复使用 props 这个词。在 ListItem 组件中,我们现在按解构后的函数参数中的名称—— {action, title, setClicked}来访问 props。

下面看看这两个变化:

import React, { useState } from 'react';import './List.css';const ListItem = ({ action, title, setClicked }) => { return { 
{ setclicked(title); action(); }} className="my-button"> {title} );};const List = ({ create, read, update, destroy }) => { const [clicked, setClicked] = useState(''); return (
The last clicked button is {clicked}
);};

太好了,我们大大减少了组件声明的长度,但是我们仍然可以做得更好!

4. 愿 PropTypes 与你同在!

经过清理之后,该是用到编写组件时最棒的实践的时候了!使用 PropTypes,我们可以验证接收到的 props,以避免由于不同数据类型而导致的错误。例如,接收字符串“0”并尝试将其与数字 0 严格对比(“0” === 0-> FALSE!!!):

import React, { useState } from 'react';import PropTypes from 'prop-types';const ListItem = ({ action, title, setClicked }) => { return ( 
{ setClicked(title); action(); }} className="my-button"> {title} );};ListItem.propTypes = { action: PropTypes.func, setClicked: PropTypes.func, title: PropTypes.string};const List = ({ create, read, update, destroy }) => { const [clicked, setClicked] = useState(''); return (
The last clicked button is {clicked}
);};List.propTypes = { create: PropTypes.func, read: PropTypes.func, update: PropTypes.func, destroy: PropTypes.func,};export default List;

PropTypes 验证

5. 切成小块

想不到吧——我们现在的组件与初始版本差不多一样长,但请仔细观察我们现在手上的代码。

我们看到了两个不同的组件,可以将它们划分为两个模块,从而使它们在整个应用程序中都能复用。

import React, { useState } from 'react';import PropTypes from 'prop-types';import ListItem from './ListItem.js'const List = ({ create, read, update, destroy }) => { const [clicked, setClicked] = useState(''); return ( 
The last clicked button is {clicked}
);};};List.propTypes = { create: PropTypes.func, read: PropTypes.func, update: PropTypes.func, destroy: PropTypes.func,};export default List;

List.js

import React, { useState } from 'react';import PropTypes from 'prop-types';const ListItem = ({ action, title, setClicked }) => { return ( 
{ setClicked(title); action(); }} className="my-button"> {title} );};ListItem.propTypes = { action: PropTypes.func, setClicked: PropTypes.func, title: PropTypes.string};export default ListItem;

ListItem.js

小 结

当你开始研究 React 组件时,本文对初始组件的这些清理工作提供了一些值得参考的优秀实践。

当然,我们可以针对这个最终结果执行其他很多优化操作,但路要一步一步走,这五个优秀实践是很好的起点。

原文链接:https://mp.weixin.qq.com/s/s90qbKR51lJl7p0ZkuFNbg

作者: 前端之巅

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

robotFramework-ride使用1-关键字驱动与数据类型

RF项目结构 项目文件夹(new project) 用例集(test suit) 测试用例(test case) RF基本功能-设置区介绍 项目 --》settings----》Document:添加用例说明 suit setup:执行此测试套件…

opencv threshold_基于深度学习OpenCV与python进行字符识别

点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达当我们在处理图像数据集时,总是会想有没有什么办法以简单的文本格式检索图像中的这些字符呢?今天我们就一起看看有没有什么简单的办法可以实现这一…

python3 robotframework+pycharm框架搭建

1.安装python3 框架组成:自动化基础库(robotframework)图形界面(robotframework-ride) 2.安装RF框架 安装robotframework。pip install robotframework -i https://pypi.doubanio.com/simple 安装robotframework-r…

delphi if多个条件_判断(if)语句

判断(if)语句目标开发中的应用场景if 语句体验if 语句进阶综合应用01. 开发中的应用场景生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?……程序中的判断if 今天发工资: ​…

excel sheet限制_Python 处理Excel内的数据(案例介绍*3)

点击上方“蓝字”关注我们了解更多精彩案例一介绍现在有一批电商产品跟当日销量的数据,如下,总共有上万笔的数据,现在需要统计每个品牌当日的销售量,比如美宝莲今天总共卖出了多少的商品,另外需要统计每个品牌下面的每…

robotFramework-ride使用2-分支与循环

1条件运算 Run keyword if 如果条件为True,则执行关键字 ELSE IF ELSE IF使用案例1: 2循环 在使用append to list前,添加Collections库 列表元素添加与删除 列表元素求和-循环 :FOR ${i} IN 1 2 3 4 5 :FOR ${i} IN RANGE 1 5FOR里面…

项目案例:在线拍卖系统_冀拓公司在张家口开展尾矿库在线监测监控系统 建设项目...

近日,受张家口弘锦矿业有限责任公司委托,冀拓公司在弘锦矿业大东沟尾矿库开展了安全风险智能在线监测监控系统施工安装服务。由于该库为“头顶库”,按照省应急管理厅要求“头顶库”必须在6月底之前完成联网,在6月24日接到项目任务…

Linux 两台服务器之间传输文件和文件夹

今天处理一个项目要迁移的问题,突然发现这么多图片怎么移过去,可能第一时间想到的是先从这台服务器下载下来,然后再上传到另外一台服务器上面去,这个方法确实是可行,但是实在是太费时间了,今天我就教大家怎…

arm汇编指令集_1. 从0开始学ARM安装Keil MDK uVision集成开发环境

关于ARM的一些基本概念,大家可以参考我之前的文章:《0.到底什么是Cortex、ARMv8、arm架构、ARM指令集、soc?一文帮你梳理基础概念【科普】》0. 如何学习arm?ARM的知识点很多很杂,很多同学都遇到过类似的问题&#xff0…

32位存储环境下整数范围为什么是[-2^31,2^31-1]?

一、概念:存储单位 1.“位”是数据存储的最小单位。在计算机中的二进制数系统中,位,简记为bit,也称为比特,每个0或1就是一个位。 2.“字节”是计算机信息技术用于计量存储容量的一种计量单位,通常情况下,…

mysql5.7配置用户名密码_MySQL57安装图解

原文:MySQL57安装图解_ma524654165的博客-CSDN博客作者: ma524654165MySQL57安装图解、、、0-需要准备的安装包1在百度下载MySQl开始安装下载的MySQL勾选同意点击Next4选择Server only5点击execute继续6点击next7直接next8配置服务器的端口-默认9设置一个…

vc6.0添加注释快捷键

第一步:工具 第二步:点击定制(Customize)-键盘-All commands-选择CommentOut,在新建快捷键处填写Ctrl/。

python 释放内存_学了4年C++后,我转向了Python

作者 | asya f 编译 | Lisa C 已经学不动了,现在换 Python 还来得及吗?一位四年工作经验的 C 程序员亲述转型历程,这不仅仅是语言上的转变,而是代码思维甚至工作环境的转变。 通常,程序员会认为 Python 编码比较简单&a…

2021-03-07

一、安装和使用Anaconda 1、anaconda是什么? Anaconda在英文中是“巨蟒”的意思,与python的意思相近,它是python的包管理器和环境管理器。 2、为什么需要安装anaconda? 原因有以下几点: 附带一大批常用的数据科学…

python如何实现模拟登录_超详细的Python实现新浪微博模拟登陆(小白都能懂)

最近由于需要一直在研究微博的爬虫,第一步便是模拟登陆,从开始摸索到走通模拟登陆这条路其实还是挺艰难的,需要一定的经验,为了让朋友们以后少走点弯路,这里我把我的分析过程和代码都附上来。 首先,我们先用…

wacom mac驱动_MAC系统装Wacom手绘板的方法及注意事项

⚠️注意事项⚠️:一般Wacom官网的驱动会比苹果最新系统更新慢很多,所以如果你是最新系统,那官网的驱动你目前肯定用不了!要找客服去单独要。电话:4008105460 如果你刚好是老系统,那么恭喜你~?…

linux mplayer_移植mplayer播放器到EK200开发板的步骤浅析

mplayer是一款开源多媒体播放器,以gnu通用公共许可证发布此款软件可在各主流操作系统使用,一方面它资源占用率低;另一方面,无论是音频还是视频方面,它支持的格式相当全面,能支持播放大部分的音频、视频格式…

printf格式字符串和输出列表个数及类型不匹配案例

printf函数不会进行任何类型转换(包括隐式转换),它只是从内存中读出你所提供的元素的值(按照%d,%f等控制字符提示的格式) void main() {int i10.0/3;float j10.0/3;printf("%d\n",i); //3printf…

脚本自动定时打开链接_自动化构建系统

在软件开发过程中,特别是在一些大型多人合作开发的项目中,如何将各个人开发的不同模块集合为一个完整的系统,最终输出一个完整的目标文件,这个过程包括编译,发布,自动化测试等环节。这一过程的完善程度和流…

++ba--运算结果解析

int db&&a--; 此运算其实的操作为&#xff1a; db&&a,然后aa-1,所以d0&#xff0c;a-1. #include<stdio.h> void main() {/*double a97.3;double b98;double c;int c1;printf("%d\n",(int)(a/b));printf("%f",a/b);*/int a0,b2,…