There are different ways of solving the same problem when it comes to programming — whether it be JavaScript, React, Python, or any other language. When you look into someone else’s code, there is always something new that you can learn.
解决同一问题时,有多种解决方法,无论是JavaScript,React,Python还是任何其他语言。 当您查看别人的代码时,总会有一些新知识可以学习。
React is evolving day by day and there are various approaches that can be used to solve any problem that we face in our application. Let’s look at ten tips and tricks that will definitely help you while working with React. Think of these tricks mostly as performance boosters for your application.
React每天都在发展,可以使用各种方法来解决我们在应用程序中遇到的任何问题。 让我们看一下十个技巧和窍门,这些技巧和窍门绝对会在使用React时为您提供帮助。 这些技巧主要是为您的应用程序带来性能提升。
1.暂停控制台调试器 (1. Pause Console Debugger)
You have surely come across a scenario where you want to debug the style of dropdown or something else that closes automatically when you try to right-click on the element and click on “Inspect element.”
您肯定会遇到一种情况,当您尝试右键单击元素并单击“检查元素”时,您要调试下拉菜单的样式或其他会自动关闭的样式。
Here is a simple solution:
这是一个简单的解决方案:
- Open your console from a browser. 从浏览器打开控制台。
- Type in the following command: 输入以下命令:
setTimeout(() => {debugger;}, 5000)
3. Then open the dropdown that you want to debug.
3.然后打开要调试的下拉菜单。
2. useState的带函数的延迟初始化 (2. useState Lazy Initialization With Function)
There are times when we need to set the initial value of the state from some variable or from a function that returns a value.
有时候,我们需要从某些变量或返回值的函数中设置状态的初始值。
Let’s take a look at the example below:
让我们看下面的例子:
const initialState = someFunctionThatCaluclatesValue(props)const [count, setCount] = React.useState(initialState)
Since our function is in the body, every time a re-render happens, this function is getting called even if its value is not required (we only need it during the initial render).
由于我们的函数在主体中,因此每次重新渲染时都会调用此函数,即使不需要它的值也是如此(我们仅在初始渲染时需要它)。
Let’s see how to lazy initialize useState
with a function:
让我们看看如何通过一个函数来延迟初始化useState
:
const getInitialState = (props) => someFunctionThatCaluclatesValue(props)const [count, setCount] = React.useState(getInitialState)
Creating a function is very fast. React will only call the function when it needs the initial value (which is when the component is initially rendered). So even if the function is taking a lot of time, it will be slow on the initial render only. This is called “lazy initialization.” It’s a performance optimization.
创建功能非常快。 React仅在需要初始值时(即组件最初被渲染时)才调用该函数。 因此,即使该功能花费大量时间,它也只会在初始渲染时变慢。 这称为“延迟初始化”。 这是性能优化。
Let’s look at this GIF to get an idea of what that looks like:
让我们看一下这个GIF,以大致了解一下:
To play around with the example above:
要玩上面的示例:
3.使用自定义挂钩 (3. Making Use of Custom Hooks)
With hooks, we don’t have some facility that can help us get the callback as in the case of setState
.
对于钩子,我们没有像setState
这样的设施可以帮助我们获取回调。
For example, we get the callback in the state. Once the state is set, we usually use the callback function:
例如,我们使回调处于状态。 设置状态后,我们通常使用回调函数:
this.setState({
"name" : "Harsh"
}, () => {
// Hey that state is set successfully what do you
// want to do, I'm callback your friend 😄
})
Let’s see how can we achieve similar behavior with a custom hook that gets called only when the state is changed and isn’t called during the initial render:
让我们看看如何使用自定义钩子实现类似的行为,该自定义钩子仅在状态更改时才被调用,而在初始渲染期间不被调用:
const App = () => {
const [state, setState] = useStateCallback(0); // same API as useState + setState with cb
const handleClick = () => {
setState(
prev => prev + 1,
// 2nd argument is callback , `s` is *updated* state
// Hey that state is set successfully what do you
// want to do, I'm callback your friend 😄
s => console.log("I am called after setState, state:", s)
);
};
return <button onClick={handleClick}>Increment</button>;
}
For more easy-to-understand hook recipes, check out Gabe Ragland.
有关更多易于理解的钩子配方,请查看Gabe Ragland 。
4.监视应用程序中不必要的渲染 (4. Monitor Unnecessary Renders in Your Applications)
One of the common problems we face is evaluating the necessary renders in your application that are having a bad impact on the performance.
我们面临的常见问题之一是评估应用程序中必要的渲染,这些渲染会对性能产生不良影响。
There are different ways we can evaluate them to avoid unnecessary renders in minutes
我们可以通过多种方式评估它们,从而避免在几分钟内产生不必要的渲染
你为什么渲染 (why-did-you-render)
According to its documentation, why-did-you-render “monkey patches React to notify you about avoidable re-renders.” This will display unnecessary renders that are happening in your application so that you can take action against them.
根据其文档, 为什么要渲染 “猴子补丁React以通知您有关可避免的重新渲染”。 这将显示应用程序中正在发生的不必要的渲染,以便您可以对它们采取措施。
React Devtools (React Devtools)
As noted by DebugBear:
如DebugBear所述 :
“DevTools give us a visualization of the performance of your app. To see this, ensure that you are running React in development mode, open DevTools in your browser, and then go to the “Performance” tab.
“ DevTools为我们提供了您应用程序性能的可视化。 为此,请确保您在开发模式下运行React,在浏览器中打开DevTools,然后转到“性能”选项卡。
You can record the performance of your app from a point after the page has loaded or from the page load. There are two buttons in the top left corner of the DevTools dialog:”
您可以在页面加载后或页面加载后的某个时间记录应用程序的性能。 DevTools对话框的左上角有两个按钮:”
Once you stop recording, you will be able to see a graph showing different components that rendered and the time taken to render them.
停止记录后,您将可以看到一个图形,其中显示了渲染的不同组件以及渲染它们所花费的时间。
5.使用React.memo和useMemo (5. Using React.memo and useMemo)
According to React's official documentation:
根据React的官方文档 :
"
React.memo
is a higher-order component.“
React.memo
是一个高阶组件。If your function component renders the same result given the same props, you can wrap it in a call to React. In some cases, memoizing the result will provide a performance boost. This means that React will skip rendering the component and reuse the last rendered result.”
如果您的函数组件在使用相同的道具时呈现相同的结果,则可以将其包装在对React的调用中。 在某些情况下,记住结果可以提高性能。 这意味着React将跳过渲染组件并重用最后渲染的结果。”
React.memo
does a shallow comparison out of the box and avoids rendering. A Stack Overflow user defined a shallow comparison as being “when the properties of the objects being compared are done using ===
or strict equality and will not conduct comparisons deeper into the properties.”
React.memo
了较浅的比较,并避免了渲染。 Stack Overflow用户将浅表比较定义为“当使用===
或严格等于完成比较对象的属性时,不会在属性中进行更深入的比较。”
Note: In the example above, true
means that the component will render again despite the values being the same.
注意:在上面的示例中, true
表示即使值相同,组件也将再次呈现。
But there are times when you need to do a deep comparison, meaning you want to compare the nested properties in an array of objects. How can we do that? Let’s jump into our next trick.
但是有时您需要进行深度比较,这意味着您想比较对象数组中的嵌套属性。 我们该怎么做? 让我们跳入下一个技巧。
6. shouldComponentUpdate中的深度比较 (6. Deep Comparison in shouldComponentUpdate)
As we saw in the example above, React.memo
can only help you to avoid re-rendering if your values are simple. But if you have a nested array of objects, you cannot compare them right out of the box.
正如我们在上面的示例中看到的那样,如果您的值很简单, React.memo
只能帮助您避免重新渲染。 但是,如果您有嵌套的对象数组,则无法立即比较它们。
Use deep-equal:
使用深度相等:
Compare two objects and return whether they are equal according to a recursive equality algorithm.
比较两个对象并根据递归相等算法返回它们是否相等。
“If
opts.strict
istrue
, use strict equality (===
) to compare leaf nodes. The default is to use coercive equality (==
) because that's howassert.deepEqual()
works by default.” — deep-equal“如果
opts.strict
为true
,请使用严格相等(===
)比较叶节点。 默认是使用强制相等(==
),因为这就是assert.deepEqual()
默认工作的方式。” — 深平等
Note: There are many such packages that can help you compare two nested arrays of objects to avoid re-rendering via comparison.
注意:有很多这样的软件包可以帮助您比较两个嵌套的对象数组,以避免通过比较重新呈现。
7.React窗口 (7. React Window)
Since most of the application has to do with rendering the data in the form of a list, when the list grows long, it’s like a poison is slowly entering your application and having a bad impact on the performance. It starts consuming a lot of memory in the browser as well. Since all the list items are in the DOM, there is a lag when you scroll the list.
由于大多数应用程序都与以列表形式呈现数据有关,因此当列表长时,就好像有毒物质缓慢进入您的应用程序,并对性能造成不良影响。 它也开始消耗浏览器中的大量内存。 由于所有列表项都在DOM中,因此滚动列表时会有滞后。
How can we render only some parts of the items on the list that are currently visible on the screen then? Make use of React Window:
我们如何只呈现列表中当前在屏幕上可见的项目的某些部分呢? 利用React Window:
No matter the size of your list (e.g. 1,000 items), it will only display 20–30 items in the DOM depending on the size of your window, which is completely customizable and will boost performance!
无论列表的大小(例如1,000个项目)如何,它都将根据窗口的大小在DOM中仅显示20–30个项目,这是完全可自定义的,将提高性能!
8.React查询 (8. React Query)
With hooks for fetching, caching, and updating asynchronous data in React, managing server state is easier than ever before with React Query.
借助用于在React中获取,缓存和更新异步数据的钩子,使用React Query管理服务器状态比以往任何时候都更加容易。
Here are the features listed on GitHub:
以下是GitHub上列出的功能:
- Transport/protocol/back-end agnostic data fetching (REST, GraphQL, promises, whatever!) 传输/协议/后端不可知数据获取(REST,GraphQL,promise等)!
- Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime) 自动缓存+重新获取(重新验证时有效,窗口重新聚焦,轮询/实时)
- Parallel + Dependent Queries 并行+从属查询
- Mutations + Reactive Query Refetching 变异+React性查询重新提取
- Multi-layer Cache + Automatic Garbage Collection 多层缓存+自动垃圾收集
- Paginated + Cursor-based Queries 分页+基于游标的查询
- Load-More + Infinite Scroll Queries w/ Scroll Recovery 带有滚动恢复的更多加载+无限滚动查询
- Request Cancellation 取消请求
React Suspense + Fetch-As-You-Render Query Prefetching
React Suspense +按需获取查询预取
9.延迟加载React组件(带有React.lazy和Suspense) (9. Lazy Loading React Components (With React.lazy and Suspense))
什么是React.lazy()? (What is React.lazy( )?)
As written by Nwose Lotanna, React.lazy
is:
正如Nwose Lotanna所写 , React.lazy
是:
“A new function in React that lets you load React components lazily through code splitting without help from any additional libraries. Lazy loading is the technique of rendering only needed or critical user interface items first, then quietly unrolling the non-critical items later.”
“ React中的新功能,可让您通过代码拆分延迟加载React组件,而无需任何其他库的帮助。 延迟加载是先呈现仅需要或关键的用户界面项目,然后再安静地展开非关键项目的技术。”
什么是悬念? (What is Suspense?)
"
Suspense
is a component required by the lazy function that is basically used to wrap lazy components. Multiple lazy components can be wrapped with the help of theSuspense
component. It also takes a fallback property that is going to accept the React elements you want to render as the lazy component is being loaded.” — Nwose Lotanna“
Suspense
是lazy函数所需的组件,基本上是用来包装lazy组件的。可以通过Suspense
组件来包装多个lazy组件。它还具有一个fallback属性,该属性将接受您想要的React元素。在加载惰性组件时呈现。” — Nwose Lotanna
See the code to play around with this on CodeSandbox.
在CodeSandbox上查看代码以解决此问题。
You can now identify any large components on a page in your application that only render on certain user interactions (like clicking a button, toggle, etc). Splitting these components will minimize your JavaScript payloads and help you increase performance.
现在,您可以在应用程序页面中标识仅在某些用户交互(例如单击按钮,切换等)时呈现的任何大型组件。 拆分这些组件将最大程度地减少JavaScript负载,并帮助您提高性能。
10.一种更新多个输入状态值的函数 (10. One Function to Update Multiple Input State Values)
This is the common use case of keeping the same function to update multiple input values. Most of us know about this approach that helps to reduce the code and get our job done. This is useful in case there are multiple inputs in a form:
这是保持相同功能以更新多个输入值的常见用例。 我们大多数人都知道这种方法,可以帮助减少代码并完成工作。 如果表单中有多个输入,这很有用:
import React from "react";
function Form() {
const [state, setState] = React.useState({
firstName: "",
lastName: ""
})
// same function can be used to update multiple values in the state
const handleChange = (evt) => {
const value = evt.target.value;
setState({
...state,
[evt.target.name]: value
});
}
return (
<form>
<label>
First name
<input
type="text"
name="firstName"
value={state.firstName}
onChange={handleChange}
/>
</label>
<label>
Last name
<input
type="text"
name="lastName"
value={state.lastName}
onChange={handleChange}
/>
</label>
</form>
);
}
结论 (Conclusion)
Did you know any of these tricks? Thanks for reading this article. I hope you learned something new!
您知道这些技巧吗? 感谢您阅读本文。 希望您学到新知识!