0

I am trying to create dynamically element on button click and append it to one of the classes by using ref.

I can use document.createElement but from what I read do not use it in react

For example I want to add an element of <p> to div with class name of classes.elements by clicking the button

import React, { useRef } from 'react'
import classes from './AddElement.scss'
const AddElement = (props) => {
  const elementRef = useRef(null)

  const addElement = () => {
   <p>This is paragraph</p>
  }

  return (
    <div>
      <button onClick={() => addElement()}>Click here</button>
      <div ref={elementRef} className={classes.elements}>

      </div>
    </div>
  )
}
export default AddElement;
4
  • what do you mean adding it to classes? Commented Aug 20, 2020 at 19:42
  • I mean to add to div with the className of classes.elements Commented Aug 20, 2020 at 19:43
  • are you trying to append a p tag or html by finding a class name while clicking on the button? Commented Aug 20, 2020 at 20:08
  • @MonzoorTamal I am trying to append p tag by finding a class name when i clicking on button. Commented Aug 20, 2020 at 20:11

4 Answers 4

2

You could try using the useState hook like this :

import React, { useState } from 'react';
import classes from './AddElement.scss';

const AddElement = () => {
  const [dynamicElems, setDynamicElems] = useState([]);

  const addElement = () => {
    // Creates the dynamic paragraph
    const newDynamicElem = <p className={classes.elements}>This is paragraph</p>;
    // adds it to the state
    setDynamicElems(() => [...dynamicElems, newDynamicElem]);
  };

  return (
    <div>
      <button onClick={() => addElement()}>Click here</button>
      <div className={classes.elements}>{dynamicElems}</div>
    </div>
  );
};
export default AddElement;
Sign up to request clarification or add additional context in comments.

Comments

0
const AddElement = (props) => {
  
  const [dynamicCompList, setDynamicCompList] = useState([]);   

  const addElement = () => {
   const dynamicEl = React.createElement("p", {}, "This is paragraph");
   setDynamicCompList(dynamicCompList.concat(dynamicEl)); 
  }

  return (
    <div>
      <button onClick={() => addElement()}>Click here</button>
      <div className={classes.elements}>
        {dynamicCompList} 
      </div>
    </div>
  )
}
export default AddElement;

Comments

0

Try this:

const addElement = () => {
  const para = document.createElement("p");
  para.innerHTML = 'Hello';
  elementRef.current.appendChild(para);
};

<div ref={elementRef}></div>
<button onClick={addElement}>Click me</button>

1 Comment

I know this method, but from what I read in the internet, you should not use document.createElement in React
0

Approach 1

import React, { useRef, useState } from "react";

import classes from "./App.module.scss";

export default function App() {
  const componetRef = useRef(null);
  const [contentValue, setContentValue] = useState([]);

  const addElement = () => {
    const content = "this is para";
    const type = componetRef.current.dataset.type || "p";
    const classNames = componetRef.current.className;

    const elemnt = React.createElement(type, { key: Date.now() }, content);

    setContentValue([
      ...contentValue, // If you dont want to make it multiple times. just remove it
      elemnt
    ]);
  };
  return (
    <div className="App">
      <button onClick={addElement}>Click here</button>

      <div data-type="h1" ref={componetRef} className={classes.tag1}>
        {contentValue}
      </div>
    </div>
  );
}

Approach 2


import React, { useState } from "react";
import classes from "./App.module.scss";

const NewComponent = ({ classNames, content }) => {
  return (
    <div className={classNames} dangerouslySetInnerHTML={{ __html: content }} />
  );
};
export default function App() {
  // const classRef = useRef(null);
  const [multiple, setMultiple] = useState([]);
  const addElement = (e) => {
    const classNames = e.target.dataset.class;
    const content = e.target.dataset.content;
    
    setMultiple([
      ...multiple, // If you dont want to make it multiple times. just remove it
      <NewComponent
        key={Date.now()}
        classNames={classNames}
        content={content}
      />
    ]);
  };
  return (
    <div className="App">
      <button
        onClick={addElement}
        data-class={classes.tag1}
        data-content={"<p>asdasd</p>"}
      >
        Click here
      </button>
      {multiple}
    </div>
  );
}

Let me know if you have more question. Here is sandbox

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.