使用循环来响应渲染组件,但是当状态更新时,它会重新渲染所有内容

时间:2019-09-17 08:57:41

标签: javascript arrays reactjs react-native state

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

Component0加载Component1,并且该组件负责初始循环,来自dummyData的每个数据都表示Component2,它具有自己的状态。在Component1的最后一个“返回”部分,我还使用手动props.name手动调用了Component2 3x。

使用此代码沙箱运行此代码时,请在控制台中查看日志。注意,当您单击任何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);

2 个答案:

答案 0 :(得分:3)

您应该更新此内容:

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;
});

希望这会有所帮助。

答案 1 :(得分:1)

替换此

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

使用

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

在React中初始化组件的方式是错误的。也可以尝试使用ForEach代替Map方法。 :)