将组件添加到 useRef 对象

Add component to useRef object

如何在 useRef 对象(引用 DOM 元素)中添加组件?

const Red = () => {
  return <div className="color">Red</div>;
};

const Black = () => {
  return <div className="color">Black</div>;
};
const Green = () => {
  return <div className="color">Green</div>;
};

const Button = (params) => {
  const clickHandler = () => {
    let boolA = Math.random() > 0.5;

    if (boolA) {
      params.containerRef.current.appendChild(<Red />);
    } else {
      let boolB = Math.random() > 0.5;

      if (boolB) {
        params.containerRef.current.appendChild(<Black />);
      } else {
        params.containerRef.current.appendChild(<Green />);
      }
    }

  };

  return <button onClick={clickHandler}>Click</button>;
};

export default function App() {
  const containerRef = useRef(null);

  return (
    <div className="App">
      <Button containerRef={containerRef} />

      <div ref={containerRef} className="color-container">
        Color components should be placed here !
      </div>
    </div>
  );
}

params.containerRef.current.appendChild(); -> 抛出错误。我用它来展示我希望发生的事情。

我正在做的也是 anti-pattern/stupid 吗?是否有另一种(更聪明的)方法来实现上述目标?

codesandbox link

编辑: 我忘记了一些重要的信息要补充。 只有 Button 知道并可以决定添加什么组件。

最好有一个在点击按钮时改变的状态。

 const [child, setChild] = useState(null);

 const clickHandler = () => {
   setChild(<Color />);
 };
const Button = (params) => {
  return <button onClick={params.onClick}>Click</button>;
};

 <Button onClick={clickHandler} />
 <div className="color-container">
   Color components should be placed here !
   {child}
 </div>

Working sandbox

编辑:如果你想在重复点击按钮时添加多种颜色,请参考@TheWuif 的回答

我认为你的代码中有几处是反模式的:

  • 直接操作真实的 dom 而不是通过虚拟的 React dom
  • 命令式而不是声明式地呈现 Color 组件

这里的代码使用useState(状态displayColor)来控制是否应该显示<Color />

import { useState } from "react";
import "./styles.css";

const Color = () => {
  return <div className="color">Color</div>;
};

const Button = (props) => {
  return <button onClick={props.clickHandler}>Click</button>;
};

export default function App() {
  const [displayColor, setDisplayColor] = useState(false);

  const clickHandler = () => {
    setDisplayColor(true);
  };

  return (
    <div className="App">
      <Button clickHandler={clickHandler} />

      <div className="color-container">
        Color components should be placed here !{displayColor && <Color />}
      </div>
    </div>
  );
}

Codesandbox

预计您要添加多种颜色,这样的东西可以工作并且不需要参考:

import { useState } from "react";
import "./styles.css";

const Color = () => {
  return <div className="color">Color</div>;
};

const Button = (params) => {
  return <button onClick={params.onClick}>Click</button>;
};

export default function App() {
  const [colors, setColors] = useState([]);

  return (
    <div className="App">
      <Button onClick={() => setColors((c) => [...c, <Color />])} />

      <div className="color-container">
        {colors}
      </div>
    </div>
  );
}