注:您可以在CodeSandbox中查看和编辑代码.

我有以下父文件,它创建了一个名为ProgressBaruseState个子元件列表:

import React, { useState } from 'react';
import ProgressBar from './ProgressBar';
import './App.css';

var idCounter = 0;

export default function App() {
  const [barsArray, setBarsArray] = useState([]);
  const [input, setInput] = useState('');

  function add() {
    setBarsArray((prev) => [
      ...prev,
      <ProgressBar key={idCounter++} restart={false} />,
    ]);
  }

  function remove() {
    setBarsArray((prev) => prev.filter((bar) => bar.key !== input));
  }

  function reset() {
    setBarsArray((prev) =>
      prev.map((bar) => (bar.key === input ? { ...bar, restart: true } : bar))
    );
  }

  return (
    <div className='App'>
      <div className='buttons'>
        <button className='button-add' onClick={add}>
          Add
        </button>
        <button className='button-delete' onClick={remove}>
          Delete
        </button>
        <button className='button-delete' onClick={reset}>
          Reset
        </button>
        <input
          type='number'
          value={input}
          onInput={(e) => setInput(e.target.value)}
        />
      </div>
      <div className='bars-container'>
        {barsArray.map((bar) => (
          <div className='bars-index' key={bar.key}>
            {bar}
            <p>{bar.key}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

子元素ProgressBar的文件具有以下内容:

import React, { useEffect, useState } from 'react';
import './ProgressBar.css';

export default function ProgressBar(props) {
  const [progress, setProgress] = useState(0);

  let interval;

  useEffect(() => {
    interval = setInterval(() => {
      setProgress((prev) => prev + 1);
    }, RnadInt(10, 120));
  }, []);

  useEffect(() => {
    if (progress >= 100) clearInterval(interval);
  }, [progress]);

  if (props.restart === true) {
    setProgress(0);
  }
  return (
    <>
      <div className='ProgressBarContainer'>
        <div className='ProgressBar' style={{ width: progress + '%' }}></div>
      </div>
    </>
  );
}

function RnadInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

我的问题是父组件中的重置按钮不起作用,就我而言,如果您将传递的props 更改为子组件,子组件会自动重新渲染,但即使我在更新父组件中reset中的props 函数,该函数将子组件的旧数组映射到新数组,并且只更改所选子组件的props .

谢谢!

推荐答案

通过add添加状态中的元素将需要保持元素的引用,而不是实际的props 绑定到元素.这里建议使用模型对象,并在呈现时使用JSX元素.

请使用下面的代码,该代码将barsArray定义为对象状态,并在以后使用它呈现ProgressBar组件(从贴图调用).

判断工作代码和框-https://codesandbox.io/s/admiring-glitter-j3b7sw?file=/src/App.js:0-1446

import React, { useState } from "react";
import ProgressBar from "./ProgressBar";
import "./App.css";

var idCounter = 0;

export default function App() {
  const [barsArray, setBarsArray] = useState([]);
  const [input, setInput] = useState("");

  function add() {
    setBarsArray((prev) => [...prev, { id: idCounter++, restart: false }]);
  }

  function remove() {
    setBarsArray((prev) =>
      prev.filter((bar) => bar.id.toString() !== input.toString())
    );
  }

  function reset() {
    setBarsArray((prev) =>
      prev.map((bar) => {
        return bar.id.toString() === input.toString()
          ? { ...bar, restart: true }
          : { ...bar };
      })
    );
  }

  return (
    <div className="App">
      <div className="buttons">
        <button className="button-add" onClick={add}>
          Add
        </button>
        <button className="button-delete" onClick={remove}>
          Delete
        </button>
        <button className="button-delete" onClick={reset}>
          Reset
        </button>
        <input
          type="number"
          value={input}
          onInput={(e) => setInput(e.target.value)}
        />
      </div>
      <div className="bars-container">
        {barsArray.map((bar) => (
          <div className="bars-index" key={bar.id}>
            <ProgressBar key={bar.id} restart={bar.restart} />
            <p>{bar.key}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

Javascript相关问答推荐

在react JS中映射数组对象的嵌套数据

类构造函数不能在没有用With Router包装的情况下调用

映射类型定义,其中值对应于键

不同表的条件API端点Reaction-redux

如何在脚本编译后直接将RxJ模块导入浏览器(无需Angel、webpack、LiteServer)

使用createBrowserRoutVS BrowserRouter的Reaction路由

我无法在Api Reaction本机上发出GET请求

bootstrap S JS赢得了REACT中的函数/加载

固定动态、self 调整的优先级队列

如何创建一个for循环,用于计算仪器刻度长度并将其放入一个HTML表中?

如何按区域进行过滤并将其从结果数组中删除?

在AgGrid中显示分组行的单元格值

如何将缓冲区数组转换回音频

如何在通过JavaScript添加图像后将其删除?

如何使用属性访问器定义循环的for...的局部变量

我正在用JS编码一个链表,而我编写的一个Prepreend函数并没有按照我的预期工作

ChartJS定义默认Y轴数据集

如何在屏幕上显示时使用Java脚本和jQuery应用排序幻灯片动画

为什么它不记录任何东西在控制台?

如何合并对象列表中的连续重复值?