10 practical tips for writing cleaner React code

青灯夜游
Release: 2023-01-03 20:18:51
forward
1598 people have browsed it

This article will share with you 10 practical tips for writing simpler React code. I hope it will be helpful to you!

10 practical tips for writing cleaner React code

1. JSX abbreviation

How to pass true value to given props? [Related recommendations:Redis Video Tutorial,Programming Video]

In the following example, use propshowTitleto display in the navigation bar component App's title:

export default function App() { return ( 
); } function Navbar({ showTitle }) { return (
{showTitle &&

标题

}
) }
Copy after login

HereshowTitleis explicitly set to a boolean valuetrue, which is not necessary because anyprovided on the component propall have a default value oftrue. So you only need to pass ashowTitlewhen calling the component:

export default function App() { return ( 
); } function Navbar({ showTitle }) { return (
{showTitle &&

标题

}
) }
Copy after login

In addition, when you need to pass a string asprops, there is no need to use curly braces{}Wrapping, you can wrap the string content in double quotes and pass it:

export default function App() { return ( 
); } function Navbar({ title }) { return (

{title}

) }
Copy after login

2. Move irrelevant code to a separate component

The easiest and most important way to write cleaner React code is to get good at abstracting the code into separate React components.

Let’s look at an example. There will be a navigation bar at the top of the application, and the data inpostswill be traversed to render the article title:

export default function App() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return ( 
    {posts.map(post => (
  • {post.title}
  • ))}
); } function Navbar({ title }) { return (

{title}

); }
Copy after login

So what do we do? How can we make this code cleaner? We can abstract the code in the loop (post titles) into a separate component and call itFeaturedPosts. The extracted code is as follows:

export default function App() { return ( 
); } function Navbar({ title }) { return (

{title}

); } function FeaturedPosts() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return (
    {posts.map((post) => (
  • {post.title}
  • ))}
); }
Copy after login

As you can see, in the App component, through the component names:NavbarandFeaturedPosts, you can quickly See what the app does.

3. Create separate files for each component

In the above example, we implemented three components in one file. If the component logic is small, there is no problem in writing these. However, if the component logic is more complex, the readability of the code written in this way will be very poor. To make your app files more readable, you can put each component into a separate file.

This can help us separate concerns in the application. This means that each file is responsible for only one component, and you won't obfuscate the source of the component if you want to reuse it in your app:

// src/App.js import Navbar from './components/Navbar.js'; import FeaturedPosts from './components/FeaturedPosts.js'; export default function App() { return ( 
); }
Copy after login
// src/components/Navbar.js export default function Navbar({ title }) { return ( 

{title}

); }
Copy after login
// src/components/FeaturedPosts.js export default function FeaturedPosts() { const posts = [ { id: 1, title: "标题1" }, { id: 2, title: "标题2" } ]; return ( 
    {posts.map((post) => (
  • {post.title}
  • ))}
); }
Copy after login

Additionally, by including each individual component in its own file , to prevent a file from becoming too bloated.

4. Move the shared function into the React hook

In the FeaturedPosts component, suppose you want to get the article data from the API instead of using fake data. You can use the fetch API to achieve this:

import React from 'react'; export default function FeaturedPosts() { 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}
  • ))}
); }
Copy after login

But what if you want to perform this data request on multiple components?

Suppose that in addition to the FeaturedPosts component, there is another component named Posts that contains the same data. We have to copy the logic for getting the data and paste it into the component. To avoid duplicating code, you can define a new React hook, which you can call useFetchPosts:

import React from 'react'; export default function useFetchPosts() { const [posts, setPosts] = React.useState([]); React.useEffect(() => { fetch('https://jsonplaceholder.typicode.com/posts') .then(res => res.json()) .then(data => setPosts(data)); }, []); return posts; }
Copy after login

This way you can reuse it in any component, including the FeaturedPosts component:

import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() return ( 
    {posts.map((post) => (
  • {post.title}
  • ))}
); }
Copy after login

5. Remove JS from JSX

Another way to simplify your components is to remove as much JavaScript as possible from JSX. Take a look at the following example:

import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() return ( 
    {posts.map((post) => (
  • { console.log(event.target, 'clicked!'); }} key={post.id}>{post.title}
  • ))}
); }
Copy after login

Here we try to handle the click event of the article, and you can see that our JSX becomes more difficult to read. Given that the function is included as an inline function, it obscures the purpose of this component, and its related functions.

How to solve this problem? You can extract the inline function containing onClick into a separate handler function and give it the name handlePostClick. In this way, the readability of JSX becomes higher:

import useFetchPosts from '../hooks/useFetchPosts.js'; export default function FeaturedPosts() { const posts = useFetchPosts() function handlePostClick(event) { console.log(event.target, 'clicked!'); } return ( 
    {posts.map((post) => (
  • {post.title}
  • ))}
); }
Copy after login

6. Formatting inline styles

Writing too many inline styles in JSX will make the The code is harder to read and becomes bloated:

export default function App() { return ( 
); } function Navbar({ title }) { return (

{title}

) }
Copy after login

We want to move inline styles into CSS stylesheets whenever possible. Or organize them into objects:

export default function App() { const styles = { main: { textAlign: "center" } }; return ( 
); } function Navbar({ title }) { const styles = { div: { marginTop: "20px" }, h1: { fontWeight: "bold" } }; return (

{title}

); }
Copy after login

Generally, it is best to write these styles in a CSS style sheet. If the style needs to be dynamically generated, it can be defined in an object.

7. Using optional chaining operators

In JavaScript, we need to first ensure that the object exists before we can access its properties. If the value of the object is undefined or null, a type error will result.

Let’s look at an example where users can edit their published posts. The EditButton component will only be displayed if isPostAuthor is true, that is, if the authenticated user's id is the same as the post author's id.

export default function EditButton({ post }) { const user = useAuthUser(); const isPostAuthor = post.author.userId !== user && user.userId; return isPostAuthor ?  : null; }
Copy after login

这段代码的问题是 user 可能是 undefined. 这就是为什么我们必须在尝试获取 userId 属性之前使用 && 运算符来确保 user 是一个对象。如果我要访问一个对象中的另一个对象,就不得不再包含一个 && 条件。 这会导致代码变得复杂、难以理解。

JavaScript 可选链运算符(?.)允许我们在访问属性之前检查对象是否存在。用它来简化上面的代码:

export default function EditButton({ post }) { const user = useAuthUser(); const isPostAuthor = post.author.userId !== user?.userId; return isPostAuthor ?  : null; }
Copy after login

这样将防止任何类型错误,并允许我们编写更清晰的条件逻辑。

8. 带括号的隐式返回

在 React 应用中可以使用 function 关键字的函数声明语法编写组件,也可以使用设置为变量的箭头函数。使用 function 关键字的组件必须在返回任何 JSX 之前使用 return 关键字。

export default function App() { return (    ); }
Copy after login

通过将返回的代码包裹在一组括号中,可以通过隐式返回(不使用 return 关键字)从函数返回多行 JavaScript 代码。

对于使用箭头函数的组件,不需要包含 return 关键字,可以只返回带有一组括号的 JSX。

const App = () => (    ); export default App;
Copy after login

此外,当使用.map()迭代元素列表时,还可以跳过return关键字并仅在内部函数的主体中使用一组括号返回 JSX。

function PostList() { const posts = usePostData(); return posts.map(post => (  )) }
Copy after login

9. 使用空值合并运算符

在 JavaScript 中,如果某个值是假值(如 null、undefined、0、''、NaN),可以使用 || 条件来提供一个备用值。

例如,在产品页面组件需要显示给定产品的价格,可以使用 || 来有条件地显示价格或显示文本“产品不可用”。

export default function ProductPage({ product }) { return ( <>   {product.price || "产品不可用"}   ); }
Copy after login

现有的代码存在一个问题,如果商品的价格为0,也不会显示产品的价格而显示"产品不可用"。如果左侧为null或者undefined,而不是其他假值,就需要一个更精确的运算符来仅返回表达式的右侧。

这时就可以使用空值合并运算符,当左侧操作数为null或者 undefined 时,将返回右侧操作数。 否则它将返回其左侧操作数:

null ?? 'callback'; // "callback" 0 ?? 42; // 0
Copy after login

可以使用空值合并运算符来修复上面代码中的问题:

export default function ProductPage({ product }) { return ( <>  {product.price ?? "产品不可用"}  ); }
Copy after login

10. 使用三元表达式

在 React 组件中编写条件时,三元表达式是必不可少的,经常用于显示或隐藏组件和元素。

当然,我们用可以使用三元表达式和模板字符串来给 React 元素动态添加或删除类名。

export default function App() { const { isDarkMode } = useDarkMode(); return ( 
); }
Copy after login

这种条件逻辑也可以应用于任何 props:

export default function App() { const { isMobile } = useDeviceDetect(); return (    ); }
Copy after login

【推荐学习:javascript视频教程

The above is the detailed content of 10 practical tips for writing cleaner React code. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!