React:如何正确处理使用状态变量的组件渲染

huangapple go评论70阅读模式
英文:

React: How to properly handle component rendering using state variables

问题

我正在尝试以顺序方式在页面上呈现不同的片段(A > B > C),想知道在使用状态变量控制这些组件的呈现方面的最佳做法是什么。

目前,我将其设置为单个状态变量:const [screen, setScreen] 并应用条件渲染:

screen === 'page1' ? <Component1 />
: screen === 'page2' ? <Component2 />
...
: 'Page Not Found'

但是,我担心这可能会在更新screen时重新渲染每个组件(或者这是否不会发生,因为screen未传递到组件本身?)。是否使用单独的状态变量来触发每个屏幕会更有效率?例如:

const [showPage1, setShowPage1] = useState(false)
const [showPage2, setShowPage2] = useState(false)
...
{showPage1 && <Component1 />}
{showPage2 && <Component2 />}
...

总的来说,我对如何减少状态变量感到困惑,并想知道将它们集中在一起是否是一种不好的做法,因为这可能会导致不必要的重新渲染。例如:

  • useContext中存储用户数据 - 更新一个键将更新整个状态,可能会触发多个组件的重新渲染
  • 在对象中存储验证检查和输入值以避免为每个单独的输入创建状态变量

请就上述情况中是否合适合并类似的状态变量提供建议。

英文:

I'm trying to render different fragments onto a page in a sequential way (A > B > C), and am wondering what the best practice is in terms of using state variables to control the rendering of these components

Currently, I have it set up as a single state variable: const [screen, setScreen] and am applying conditional rendering:

  screen === &#39;page1&#39; ? &lt;Component1 /&gt;
: screen === &#39;page2&#39; ? &lt;Component2 /&gt;
...
: &#39;Page Not Found&#39;

However, I am concerned this might lead to re-rendering of each component when screen is updated (or would this not happen because screen isn't passed into the component itself?). Would having a separate state variable to trigger each screen be more efficient? For example:

const [showPage1, setShowPage1] = useState(false)
const [showPage2, setShowPage2] = useState(false)
...
{showPage1 &amp;&amp; &lt;Component1 /&gt;}
{showPage2 &amp;&amp; &lt;Component2 /&gt;}
...

In general, I'm confused about how to reduce state variables and am wondering if clustering them together is a bad practice as it may lead to unnecessary re-renders. For example:

  • Storing user data in useContext - updating one key updates the entire state and will likely trigger re-renders in multiple components
  • Storing validation check and input values in an object to avoid having a state variable for each individual input

Please advise on whether it's appropriate to consolidate similar state variables in the above context

答案1

得分: 2

以下是已翻译好的内容:

"这个问题没有明确的答案,因为不同的方法可能根据应用程序的上下文和复杂性具有不同的优势和劣势。

但我认为这是一种简单直接的实现顺序渲染的方法,因为你只需要更新一个状态变量来在屏幕或步骤之间切换。

const [screen, setScreen] = useState("page1");

return (
  <div>
    {screen === "page1" ? (
      <Component1 onNext={() => setScreen("page2")} />
    ) : screen === "page2" ? (
      <Component2 onNext={() => setScreen("page3")} />
    ) : screen === "page3" ? (
      <Component3 />
    ) : (
      "Page Not Found"
    )}
  </div>
);

"

英文:

There is no definitive answer to this question, as different methods may have different advantages and disadvantages depending on the context and complexity of your application.

But I think this is a simple and straightforward way to implement sequential rendering, as you only need to update one state variable to switch between screens or steps.

const [screen, setScreen] = useState(&quot;page1&quot;);

return (
  &lt;div&gt;
    {screen === &quot;page1&quot; ? (
      &lt;Component1 onNext={() =&gt; setScreen(&quot;page2&quot;)} /&gt;
    ) : screen === &quot;page2&quot; ? (
      &lt;Component2 onNext={() =&gt; setScreen(&quot;page3&quot;)} /&gt;
    ) : screen === &quot;page3&quot; ? (
      &lt;Component3 /&gt;
    ) : (
      &quot;Page Not Found&quot;
    )}
  &lt;/div&gt;
);

答案2

得分: 2

以下是您要翻译的内容:

  1. "The two approaches do exactly the same thing, the only difference is the number of useState hooks you are using when a state update occurs in the parent component it will rerender and then check what to return based on state value. having one or two states makes no difference."

  2. "I am concerned this might lead to re-rendering of each component when the screen is updated. It will only do for components within the returned JSX so if screen === 'page2' then only <Component2 /> will rerender."

  3. "Storing validation check and input values in an object to avoid having a state variable for each individual input. There are some alternatives as using refs for inputs you can do then validate before submitting or packages as Formik that can help you validate, but it is ok to make a state for inputs and if you want good performance you want to avoid rerendering the whole component so you can create a child component only for your form so it rerenders on its own."

  4. "Storing user data in useContext - updating one key updates the entire state and will likely trigger re-renders in multiple components. This will rerender only mounted components using the context and we want to do that to track user changes in each one of them that's great however if it is a case when you have multiple mounted components consuming the same context better to avoid that and just pass a state from the parent to each one of them, you see it depends on the case."

英文:

The two approaches do exactly the same thing, the only difference is the number of useState hooks you are using<br> when a state update occurs in the parent component it will rerender and then check what to return based on state value.<br> having one or two states makes no difference.

> I am concerned this might lead to re-rendering of each component when screen is updated

it will only do for components within the returned JSX so if screen === &#39;page2&#39; then only &lt;Component2 /&gt; will rerender

>Storing validation check and input values in an object to avoid having a state variable for each individual input

there are some alternatives as using refs for inputs you can do then validate before submitting or packages as Formik that can help you validate, but it is ok to make a state for inputs and if you want good performance you want to avoid rerendering the whole component so you can create a child component only for your form so it rerenders on its own

>Storing user data in useContext - updating one key updates the entire state and will likely trigger re-renders in multiple components

This will rerender only mounted components using the context and we want to do that to track user changes in each one of them that's great however if it is a case when you have multiple mounted components consuming the same context better to avoid that and just pass a state from the parent to each one of them, you see it depends on the case

答案3

得分: 1

有两种重新渲染类型:

必要的重新渲染

对于引起更改的组件或直接使用新信息的组件的重新渲染。例如,如果用户在输入字段中输入文本,管理其状态的组件需要在每次按键时更新自身,即重新渲染。

不必要的重新渲染

通过不同的重新渲染机制在应用程序中传播的组件的重新渲染,要么是由于错误,要么是由于低效的应用程序架构。例如,如果用户在输入字段中输入文本,而整个页面在每次按键时重新渲染,那么页面就被不必要地重新渲染了。

单独的不必要重新渲染并不是问题:React 非常快,通常能够处理它们,而用户不会注意到任何问题。

但是,如果重新渲染发生得太频繁和/或在非常重的组件上发生,这可能会导致用户体验感觉“卡顿”,在每次交互时出现可见的延迟,甚至使应用程序完全无响应。

因此,重新渲染的流程是,如果状态变量发生变化,它会触发所有子组件以及组件本身的重新渲染,但整个应用程序不会重新渲染。因此,可以说将应用程序分解为最佳单元大小可以真正有助于此,因为为小的更改重新渲染小组件的负载要比重新渲染整个应用程序或大型组件要小得多。因此,在创建应用程序时考虑这一点非常重要。

我找到了一篇与此相关的文章,这应该会有所帮助:https://www.developerway.com/posts/react-re-renders-guide

英文:

There are two types of re-renders:

Necessary re-render

re-render of a component that is the source of the changes, or a component that directly uses the new information. For example, if a user types in an input field, the component that manages its state needs to update itself on every keystroke, i.e. re-render.

Unnecessary re-render

re-render of a component that is propagated through the app via different re-renders mechanisms due to either mistake or inefficient app architecture. For example, if a user types in an input field, and the entire page re-renders on every keystroke, the page has been re-rendered unnecessarily.

Unnecessary re-renders by themselves are not a problem: React is very fast and usually able to deal with them without users noticing anything.

However, if re-renders happen too often and/or on very heavy components, this could lead to user experience appearing “laggy”, visible delays on every interaction, or even the app becoming completely unresponsive.

so flow of re-renders is if a state variable changes it triggers re-renders in all the child components and the component itself but the whole app is not re-rendered. By this we can say that breaking up the application into optimal unit sizes can really help with this as re-rendering small components for small changes is way less load than re-rendering whole application or massive components. So it is important to make the application with this in mind.

I have found a article on the same, this should help:- https://www.developerway.com/posts/react-re-renders-guide

huangapple
  • 本文由 发表于 2023年7月10日 14:01:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76651002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定