让你的 React 代码更好更简洁的技巧

2025-06-08

让你的 React 代码更好更简洁的技巧

训练营擅长将海量信息浓缩成15周的短小精悍的课程,让你快速上手,从零开始构建完整的Web应用。然而,它们却不擅长提供足够的时间,让你真正发挥应用的最大潜力。当然,现实世界的工作也大同小异,时间限制和产品压力意味着需要将完整的愿景分解成更易于管理的部分。

尽管如此,我最近还是回到了我在训练营期间做的最喜欢的项目之一,一个名为“虚拟画布”的项目,并花了另外三个星期彻底改造页面的样式和流程,以便用户获得更加无缝、专业和整体设计更好的体验,展示我辛勤工作的成果。

在此过程中,我将所有 CSS 样式转换为 SCSS 或 SASS,而不是将所有样式打包到一个 index.scss 或 app.scss 文件中,而是采用了更模块化的样式方法,将 scss 直接添加到 JavaScript 组件旁边。说实话,这极大地改善了我的文件结构,并促使我更像 React 那样思考。这也引出了我目前提出的如何大幅改进 React 代码编写方法的建议……

让编写组件变得不方便

让我解释一下。当我第一次开始用 React 编写组件时,我倾向于不以可复用的方式处理组件。这几乎就像你一有需求就编写新组件,而完全不考虑单个组件是否真的能够满足更多需求。不幸的是,组件有时只是为了一时兴起而创建,而不是经过深思熟虑地设计以扩展或满足各种不同的需求。

当我选择将我的 js 组件与附带的 sass 文件捆绑到一个命名准确的文件夹中时(例如,将“Button.js”和“Button.scss”放入 Button 文件夹中),这极大地迫使我以一种可复用的方式思考这个组件。此外,这增加了创建组件的更多步骤,因为除了一些 javascript 文件之外,你还需要创建更多文件。

此外,这种模块化文件结构在视觉上提醒我们,该组件拥有自己的独立逻辑,并且与之前编写的组件完全不同。

用例怎么样

重构原始代码时,我的 React 应用的不同区域出现了多个表单组件实例。一个用于登录,一个用于登录,等等。显然,为了完成一个为期三周的项目,你必须走捷径,但我认为这是编写表单组件的好机会。然而,我的应用中有很多表单,包括登录、登录或创建画布表单,它们都带有不同的标签、输入和内部状态。

然而,它们内部的逻辑都大同小异,只是名称不同。因此,我编写了这个表单组件,它会根据我输入的不同 props 来改变内部状态、标签和输入:

import React, { useState } from "react"
import "./Form.scss"

const Form = props => {
    const [data, setData] = useState({})

    const renderInputs = () => {
        return props.inputs.map(input => {
            return (
                <div className="field"> 
                    <label htmlFor={input.name} >{input.name}</label>
                    <input placeholder="" type="text" id={input.name} name={input.name} />
                </div>
            )
        })
    }

    const renderPassword = () => {
        if (props.hasOwnProperty("password")) {
            return (
                <div className="field">
                    <label htmlFor="password" >Password</label>
                    <input type="password" id="password" name="password"></input>
                </div>
            )
        }
    }

    const handleFormChange = (event) => {
        event.persist()
        const {name, value} = event.target
        setData({
            ...data,
            [name]: value
        })
    }

    const handleSubmit = (event) => {
        event.preventDefault()
        props.handleSubmit(data)
    }

    return (
        <form className="form" onChange={handleFormChange} onSubmit={handleSubmit}>
            {renderInputs()}
            {renderPassword()}
            <button type="submit" className="btn-secondary">{props.submitText}</button>
        </form>
    )
}

export default Form

我现在从上到下讲解一下。我们希望每个表单都受控,所以这个抽象的表单组件一开始会以一个空对象作为内部状态。表单会接收一个“input”数组作为 props,因为这些数组元素都是构造每个表单输入的对象。

为了呈现我们的输入字段,我们将通过输入数组和输出标签以及输入 HTML 标签进行映射,并使用此输入应该描述的内容填充 HTML(我使用了名称属性,您可以想象可以向输入对象添加更多规范来指定输入 HTML)。

另外,由于我的一些表单需要密码,而另一些则不需要,我指定此表单组件将接受一个布尔值类型的 password 属性。如果 password 属性为 true,则创建一个密码字段。如果为 false,则不创建。

我觉得这很酷。既然状态目前是一个空对象,那么状态如何准确地改变以表示表单的变化呢?好吧,如果我们为每个输入框指定一个 name 属性,那么 onChange 事件就可以拾取已更改的正确输入框,完全脱离表单的实际内容。该事件将捕获输入框的当前值和名称,然后将名称和值记录到状态对象中。如果输入框的名称完全相同,那么这种实现方式可能会出现一些可预见的问题,但这其实很容易避免。

最后,提交处理程序会将状态中的数据提交给我们作为 props 传递的名为“handleSubmit”的回调函数。这使我们能够进一步抽象表单中的具体实现细节,以便我们可以轻松地在整个应用程序中轻松重用表单,并且随着应用程序的扩展,表单具有足够的可定制性以满足我们的需求。

结论

我认为,限制组件数量,甚至使用不方便编写更多组件的文件结构进行练习,可以显著提升你的 React 水平。这是一个很好的练习,可以迫使你形成一种以良好方式实现可扩展性和可复用性的思维模式。

鏂囩珷鏉ユ簮锛�https://dev.to/christiankastner/the-tip-to-make-your-react-code-better-and-cleaner-3n16
PREV
为优秀程序员提供的代码审查实用工具
NEXT
让您的网站在 Facebook、Twitter 和 LinkedIn 上可共享