【问题标题】:Add component to useRef object将组件添加到 useRef 对象
【发布时间】:2022-01-10 15:16:14
【问题描述】:

如何在 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(); -> 抛出错误。我已经用它来表明我想要发生的事情。

我也在做一个反模式/愚蠢的事情吗?是否有另一种(更智能)的方式来实现上述目标?

codesandbox link

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

【问题讨论】:

  • 你不能使用 appendChild 并传递一个 react 组件。
  • 我把代码留在那里是为了展示我想要完成的事情。

标签: reactjs react-hooks use-ref


【解决方案1】:

希望你想添加多种颜色,这样的东西可以工作并且不需要参考:

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

【讨论】:

  • 我编辑了帖子以更好地解释自己。我想如果我将 setColors 提供给 Button。而在 ButtonsclickHandler 中使用它就像 -> params.setColors() 会解决我的问题。但这样做是否正确?
  • 您不能直接使用 setState 从其子组件中设置父组件的状态,但您可以通过传递调用 setState 的函数。
  • 我明白了,这解决了我的问题。非常感谢。
【解决方案2】:

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

 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 答案

【讨论】:

    【解决方案3】:

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

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

    这是使用useState(状态displayColor)来控制是否应显示&lt;Color /&gt;的代码

    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

    【讨论】:

    • 感谢您的回答,它确实解决了我最初发布的问题,但是因为我未能准确解释我的问题是什么以及我想要实现它现在需要什么。
    猜你喜欢
    • 2022-01-13
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多