大家好,我是小义。今天分享的内容是如何写出干净的React代码。文本作为React开发人员,我们都希望编写更干净、更简单、更易于阅读的代码。在本指南中,我汇总了七种编写更清晰的React代码的最佳方法,使构建React项目和审查代码变得更加容易。总的来说,学习如何编写更简洁的React代码会让你成为一个更有价值、更快乐的React开发人员,所以让我们马上开始吧!涉及的要点是:明智地使用jsx。将不相关的代码移到单独的组件中。为每个组件创建单独的文件。将共享功能移动到React钩子中。从你的JSX中移除尽可能多的JavaScript。格式化内联样式以减少臃肿的代码。明智地使用React上下文。正确使用JSX如何将真值传递给给定的prop?在下面的示例中,我们使用showTitle在Navbar组件中显示应用程序的标题。//src/App.jsexportdefaultfunctionApp(){return();}functionNavbar({showTitle}){return(
{showTitle&&
MySpecialApp
})}我们是否需要将showTitle显式设置为布尔值true?我们不!一个快速的简写是为组件上提供的任何属性设置默认值true。因此,如果我们在Navbar上添加showTitle,我们的标题元素就会显示。//src/App.jsexportdefaultfunctionApp(){return(
);}functionNavbar({showTitle}){return(
{showTitle&&
MySpecialApp
}//titleshown!)}另一个需要记住的有用速记涉及传递字符串prop。当你传递一个字符串值时,你不需要用大括号把它包起来。如果我们要设置导航栏的标题,在使用title属性时,可以将其值放在双引号中。//src/App.jsexportdefaultfunctionApp(){return(
);}functionNavbar({title}){return(
{title}
)}将不相关的代码移到一个单独的组件中可以说,编写更清晰的React代码的最简单和最重要的方法是善于将我们的代码抽象到单独的React组件中。让我们看下面的例子://src/App.jsexportdefaultfunctionApp(){constposts=[{id:1,title:"HowtoBuildYouTubewithReact"},{id:2,title:"HowtoWriteYourFirstReactHook"}];return(
{posts.map(post=>({post.title}))}
);}functionNavbar({title}){return(
{title}
);}我们的应用程序正在显示导航栏组件。我们正在使用.map()遍历一系列帖子并在页面上显示它们的标题。我们想了一个问题,怎样才能让它更干净呢?为什么我们不获取我们正在循环的代码,将其抽象化,并将它们显示在一个单独的组件中,我们称之为FeaturePosts。让我们看看改进后的结果://src/App.jsexportdefaultfunctionApp(){return(
);}functionNavbar({title}){return(
{title}
);}functionFeaturedPosts(){constposts=[{id:1,title:"HowtoBuildYouTubewithReact"},{id:2,title:"HowtoWriteYourFirstReactHook"}];return(
{posts.map((post)=>({post.title}))}
);}如你所见,我们现在可以只看我们的App组件了。通过读取应用程序中的组件名称,Navbar和FeaturePosts,我们可以准确地看到我们的应用程序正在显示什么。为每个组件创建单独的文件在我们之前的示例中,我们将所有组件放在一个文件中,即app.js文件。类似于我们如何将代码抽象为独立的组件以使我们的应用程序更具可读性,为了使我们的应用程序文件更具可读性,我们可以将我们拥有的每个组件放在一个单独的文件中间。这再次帮助我们在应用程序中分离关注点。这意味着每个文件只负责一个组件,如果我们想在我们的应用程序中重用一个组件,就不会混淆它的来源。//src/App.jsimportNavbarfrom'./components/Navbar.js';importFeaturedPostsfrom'./components/FeaturedPosts.js';exportdefaultfunctionApp(){return(
);}我们来看看Navbar中的代码://src/components/Navbar.jsexportdefaultfunctionNavbar({title}){return(
{title}
);}接下来我们看FeaturedPosts中的代码://src/components/FeaturedPosts.jsexportdefaultfunctionFeaturedPosts(){constposts=[{id:1,title:"HowtoBuildYouTubewithReact"},{id:2,title:"HowtoWriteYourFirstReactHook"}];return(
{posts.map((post)=>({post.title}))}
);}此外,通过放置每个将各个组件包含在它们自己的文件中,我们可以避免一个文件变得过于臃肿。如果我们要将所有组件都添加到app.js文件中,我们很容易看到我们的app.js文件变得非常大。将共享功能移动到React挂钩中看看我们的FeaturePosts组件,并假设我们不显示静态帖子数据,而是想从API获取帖子数据。我们可以使用fetchAPI来完成。可以看到如下结果://src/components/FeaturedPosts.jsimportReactfrom'react';exportdefaultfunctionFeaturedPosts(){const[posts,setPosts]=React.useState([]);React.useEffect(()=>{fetch('https://jsonplaceholder.typicode.com/posts').then(res=>res.json()).then(data=>setPosts(data));},[]);return(
{posts.map((post)=>({post.title}))}
);}但是如果我们要在多个组件中执行应该我们如何处理这个数据请求?例如,除了FeaturePosts组件,我们还想创建一个具有相同数据的Post组件。我们将不得不复制我们用来获取数据的逻辑并将其粘贴到该组件中。为了避免这样做,为什么我们不使用新的Reacthook我们可以调用useFetchPosts://src/hooks/useFetchPosts.jsimportReactfrom'react';exportdefaultfunctionuseFetchPosts(){const[posts,setPosts]=React.useState([]);React.useEffect(()=>{fetch('https://jsonplaceholder.typicode.com/posts').then(res=>res.json()).then(data=>setPosts(data));},[]);returnposts;}一旦我们在专用的“hooks”文件夹中创建了这个钩子,我们就可以在我们喜欢的任何组件中重用它,包括我们的FeaturePosts组件://src/components/FeaturedPosts.jsimportuseFetchPostsfrom'。./hooks/useFetchPosts.js';exportdefaultfunctionFeaturedPosts(){constposts=useFetchPosts()return(
{posts.map((post)=>({post.title}}li>))}
);}从你的JSX中尽可能多地移除JavaScript另一种非常有用但经常被忽视的清理组件的方法是尽可能多地从我们的JSX中移除JavaScript。让我们看看下面的例子://src/components/FeaturedPosts.jsimportuseFetchPostsfrom'../hooks/useFetchPosts.js';exportdefaultfunctionFeaturedPosts(){constposts=useFetchPosts()return(
{posts.map((post)=>({console.log(event.target,'clicked!');}}key={post.id}>{post.title}))}
);}我们正在尝试处理帖子的点击事件。如您所见,我们的JSX变得更难阅读了。鉴于我们的函数作为内联函数包含在内,它掩盖了该组件及其相关函数的用途。我们可以做些什么来解决这个问题?我们可以将连接到onClick的内联函数提取到一个单独的处理程序中,我们可以给它一个合适的名称,如handlePostClick。一旦我们这样做,我们的JSX将再次可读。//src/components/FeaturedPosts.jsimportuseFetchPostsfrom'../hooks/useFetchPosts.js';exportdefaultfunctionFeaturedPosts(){constposts=useFetchPosts()functionhandlePostClick(event){console.log(event.target,'clicked!');}return(
{posts.map((post)=>({post.title}))}
);}格式内联减少代码膨胀的样式React开发人员经常在他们的JSX中编写内联样式。然而,这使得我们的代码更难阅读,也更难编写额外的JSX。//src/App.jsexportdefaultfunctionApp(){return(
);}functionNavbar({title}){return({title} )}我们希望将这种关注点分离概念应用于我们的JSX样式,将我们的内联样式移动到CSS样式表中,我们可以将其导入到我们喜欢的任何组件中。覆盖内联样式的另一种方法是将它们组织到对象中。你可以在这里看到这个模式的样子://src/App.jsexportdefaultfunctionApp(){conststyles={main:{textAlign:"center"}};return(