在 React 中复制元素

Usi*_*iel 0 javascript reactjs react-hooks

您好,感谢您的帮助,在反应中使用以下代码,我想在每次单击按钮时复制单击按钮。目前没有任何反应,但如果控制台显示数组增长。这里是沙箱:

https://codesandbox.io/s/charming-glitter-0ntxmj?file=/src/App.js

const { useEffect, useState } = React;

function App() {
  const btn = [
    <button
      onClick={() => {
        btn.push(btn[0]);
        console.log(btn);
      }}
    >
      Click
    </button>
  ];

  /*  useEffect(()=>{
btn
  },[btn])*/

  return (
    <div className="App">
      <div>
        {btn.map((e) => {
          return e;
        })}
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

Bri*_*son 5

更新函数组件中的局部变量不是这样的。它的行为就像普通函数一样,btn仅在执行期间存在App()

为了在渲染之间保留值,您需要使用state。然而,状态和道具的更新是唯一首先导致重新渲染的事情,因此App可能只在开始时渲染一次。

如果您直接将其转换为使用状态,您将遇到在状态中存储组件的反模式。为了避免这种情况,我们应该修改逻辑以仅在状态数组中存储一些通用项,以便我们的渲染逻辑可以使用它来确定要渲染的按钮数量。

考虑以下选项:

const { useState } = React;

function App() {
  const [btns, setBtns] = useState(['value'])
  
  function handleAdd() {
    setBtns((prev) => ([...btns, 'value']));
  }

  return (
    <div className="App">
      <div>
        {btns.map((e) => (
          <button
            onClick={handleAdd}
          >
            Click
          </button>
        ))}
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

您可以通过仅存储状态中按钮的数量来进一步简化:

const { useState } = React;

function App() {
  const [btnCount, setBtnCount] = useState(1)
  
  function handleAdd() {
    setBtnCount(btnCount + 1);
  }

  return (
    <div className="App">
      <div>
        {Array.from({ length: btnCount}).map((e) => (
          <button
            onClick={handleAdd}
          >
            Click
          </button>
        ))}
      </div>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)