Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 为什么组件在单击时重新渲染,并且状态发生更改?_Reactjs - Fatal编程技术网

Reactjs 为什么组件在单击时重新渲染,并且状态发生更改?

Reactjs 为什么组件在单击时重新渲染,并且状态发生更改?,reactjs,Reactjs,为什么在onClick中更改状态时,react中的整个组件会重新呈现 exmaple: 当您单击数字时,整个组件将重新渲染,如果您从on click函数中删除setCount,它将正常工作 组件背后的想法是将一个活动类添加到您单击的数字中,它更新了一个随机计数器,该计数器阻止将活动类添加到该计数器中,因为它会重新呈现整个组件 编辑:也在这里编码 import React, { useState } from "react"; const Hours = () => { const d

为什么在onClick中更改状态时,react中的整个组件会重新呈现

exmaple:

当您单击数字时,整个组件将重新渲染,如果您从on click函数中删除setCount,它将正常工作

组件背后的想法是将一个活动类添加到您单击的数字中,它更新了一个随机计数器,该计数器阻止将活动类添加到该计数器中,因为它会重新呈现整个组件

编辑:也在这里编码

import React, { useState } from "react";

const Hours = () => {
  const days = [1, 2, 3, 4, 5, 6];
  const [count, setCount] = useState(1);

  const TestClick = (e, item) => {
    setCount(count + 1);
    e.currentTarget.className = "active";
  };

  const HandleHours = () => {
    let block = <span />;
    if (days) {
      block = days.map((hour, index) => {
        return (
          <span
            style={{ display: "block" }}
            onClick={e => {
              TestClick(e, hour);
            }}
            className={`col-md-4`} key={index}>
            {hour}
          </span>
        );
      });
    }
    return block;
  };

  return (
    <div>
      <HandleHours />
    </div>
  );
};

export default Hours;

这是组件状态更改时重新加载的反应方式。当调用setState函数时,状态钩子会重新加载它所在的整个组件,setState函数是数组中useState返回的第二个元素

如果要在单击时更改元素的类,则需要将其存储为状态。在您的代码中,单击span的类会在单击时更新,但紧接着该组件会被重新命名并设置为HandleHours返回的值

我可能会有一个状态来跟踪哪一天被点击,并相应地呈现,不确定您为什么需要计数,但我把它放在那里了:

import React, { useState } from "react";
const Hours = () => {
  const days = [1, 2, 3, 4, 5, 6];
  const [count, setCount] = useState(1);
  const [clickedDays, setClickedDays] = useState([]); // Added clickedDays state

  const TestClick = (e, item, isDayClicked) => {
    setCount(count + 1);
    if (!isDayClicked) { // Setting clicked days if they are not in the array yet
      setClickedDays([...clickedDays, item])
    }
  };

  const HandleHours = () => {
    let block = <span />;
    if (days) {
      block = days.map((hour, index) => {
        const isDayClicked = clickedDays.includes(hour);
        return (
          <span
            style={{ display: "block" }}
            onClick={e => {
              TestClick(e, hour, isDayClicked);
            }}
            className={isDayClicked ? 'active' : 'col-md-4'} // Setting different class depending on state
            key={index}
          >
            {hour}
          </span>
        );
      });
    }
    return block;
  };

  return (
    <div>
      <HandleHours />
    </div>
  );
};

export default Hours;

这里的问题不是来自HandleHours组件渲染的事实,而是因为每次更改Hours组件中的状态时都会重新装载它

之所以会出现这种情况,是因为HandleHours被定义为小时内的组件,并且每当小时重新呈现对HandleHours的新引用时,就会创建一个新的引用,愚人会认为该组件与DOM分离,并有一个新组件替换它,因为它本质上是在引用上工作的

现在当你渲染HandleHours时

当您这样做时,HandleHours组件不会重新安装在每个小时重新加载组件上,并且它会正确地维护DOM元素


伯爵在那里是为了表明我所面临的问题,但我发现了问题所在,看看我的回答你在寻找不同的答案吗?
<div>
  { HandleHours () }
</div>
import React, { useState } from "react";
import "./styles.css";

const HandleHours = ({ days, TestClick }) => {
  let block = <span />;
  if (days) {
    block = days.map((hour, index) => {
      return (
        <span
          style={{ display: "block" }}
          onClick={e => {
            TestClick(e, hour);
          }}
          className={`col-md-4`}
          key={index}
        >
          {hour}
        </span>
      );
    });
  }
  return block;
};

const days = [1, 2, 3, 4, 5, 6];
const Hours = () => {
  const [count, setCount] = useState(1);

  const TestClick = (e, item) => {
    setCount(count + 1);
    console.log("TestClick");
    e.currentTarget.className = "active";
  };

  return (
    <div>
      <HandleHours days={days} TestClick={TestClick} />
    </div>
  );
};

export default Hours;