【问题标题】:React Render Components with Loop, but when state update it re-renders everything使用循环反应渲染组件,但是当状态更新时它会重新渲染所有内容
【发布时间】:2020-01-18 02:41:34
【问题描述】:

我的循环有问题。在示例代码下方,请注意我有一个对象数组作为 dummyData。

Component0 加载 Component1,该组件负责初始循环,dummyData 中的每个数据代表 Component2,它有自己的状态。在 Component1 的最后“return”部分,我还手动调用了 Component2 3x 和手动 props.name。

当您使用此代码沙箱运行此代码时,请检查控制台中的日志。请注意,当您单击任何 STATIC 时,它只会呈现 Component2,但当您单击任何 DYNAMIC 时,它会呈现 Component1,这是错误的,因为这将再次启动循环。

沙盒:https://codesandbox.io/embed/sharp-leftpad-4t9yi

import React, { useState } from "react";
import ReactDOM from "react-dom";

const dummyData = [
  { name: "DYNAMIC 1" },
  { name: "DYNAMIC 2" },
  { name: "DYNAMIC 3" },
  { name: "DYNAMIC 4" },
  { name: "DYNAMIC 5" }
];

const Component0 = () => {
  console.log("FIRST RENDER");
  return (
    <div className="App">
      <Component1 dataList={dummyData} />
    </div>
  );
};

const Component1 = props => {
  console.log("SECOND RENDER");

  let listDom = null;
  let listDoms = [];

  props.dataList.map(data => {
    listDom = Component2(data);
    listDoms.push(listDom);
    return 1;
  });

  return (
    <React.Fragment>
      <Component2 name="STATIC 1" />
      <Component2 name="STATIC 2" />
      <Component2 name="STATIC 3" />
      {listDoms}
    </React.Fragment>
  );
};

const Component2 = props => {
  let showed = true;
  const [listState, setListState] = useState(showed);

  const handleClick = props => {
    showed = listState ? false : true;
    setListState(showed);
  };

  if (listState) {
    console.log("RENDER : " + props.name);
    return (
      <div key={props.name}>
        <a href="#!" onClick={() => handleClick()}>
          <h1>{props.name}</h1>
        </a>
      </div>
    );
  } else {
    return null;
  }
};

const rootElement = document.getElementById("root");
ReactDOM.render(<Component0 />, rootElement);

【问题讨论】:

  • 这两个答案实际上都是正确的。 JSX 编译为普通的 js 函数调用。例如:&lt;Component2 name={data.name} /&gt; 变为 createElement(Component2, {name: data.name})。当您传递一个普通函数Component2(data) 时,它不会被createElement 包装。我想这在这里很重要。

标签: javascript arrays reactjs react-native state


【解决方案1】:

你应该更新这个:

let listDoms = [];

  props.dataList.map(data => {
    listDom = Component2(data);
    listDoms.push(listDom);
    return 1;
  });

对此:

let listDoms = props.dataList.map(data => {
    listDom = <Component2 key={data.name} name={data.name} />;
    return listDom;
});

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    替换这个

    listDom = Component2(data);
    listDoms.push(listDom);
    

    listDoms.push(<Component2 name={data.name}/>)
    

    您在 React 中初始化组件的方式是错误的。也尝试使用 ForEach 而不是 Map 方法。 :)

    【讨论】:

    • @Valibhav 为什么选择 ForEach?我只在需要中断循环时使用它,地图更快?
    • @SamTaps Map 用于更改列表的值并返回一个新列表,当您想要更改同一列表的值而不是创建新列表时使用 foreach。
    • 要了解差异,请检查我的答案和@Stavros 的答案,他正在创建一个列表,而我正在插入现有列表。
    • @SamTaps 没问题 :)
    • 实际上更快的是一个简单的 for 循环,但对于您的数据大小,它不应该有所作为。我一直在使用 map,因为我尽量不要过多地更改原始代码以避免混淆询问的人,并且我更新了它以正确使用(因为 push 和 return 1 不是正确的方法)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 2019-04-03
    • 2021-10-15
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多