0

I am trying to create a dynamic mui grid element when a button is pressed in a react component. When I tried to create let newGrid = document.createElement('Grid') it does not work as a normal div creation.

Any suggestions?

Current code snippet:

return (
    <>
        <button onClick={addRow}>Add Row</button>
        <Grid container className='v-timeline-container'>
            <Grid xs={12} item className="v-timeline-item v-center v-border">
                <TextItems />
            </Grid>
        </Grid>

    </>
   
)

What I am trying to achieve dynamically:

return (
    <>
        <button onClick={addRow}>Add Row</button>
        <Grid container className='v-timeline-container'>
            <Grid xs={12} item className="v-timeline-item v-center v-border">
                <TextItems />
            </Grid>
            <Grid xs={12} item className="v-timeline-item v-center v-border">
                <TextItems />
            </Grid>
        </Grid>

    </>
   
)
  

2 Answers 2

2

React uses a VDOM to keep track of stuff internally, you manipulating the DOM directly using DOM APIs is considered dangerous. What you should do this something like this.

function App(){
 // you probably want to track the text items in each row, 
 // so use an array of objects
 const [gridItems, setGridItems] = useState([]);

 // this function adds a new grid item
 const onClick = () => {
  setGridItems([...gridItems, {text: "new row", id: gridItems.length + 1}]);
 };

 return (
    <>
         <button onClick={onClick}>Add Row</button>
         <Grid container className='v-timeline-container'>
          {
            gridItems.map(item => (
             <Grid xs={12} item className="v-timeline-item v-center v-border">
                <TextItems>{item.text}</TextItems>
             </Grid>
            ))
          }
         </Grid>
    </>
 );
}
Sign up to request clarification or add additional context in comments.

Comments

2

Using setState is a solution. It increments a number in state to create an array from it. In your case you will certainly push new data to an array when you click on the button. But you get the idea.

import React, { useState } from 'react';
import { Grid } from '@mui/material'

const ListItems = () => {
  const [items, setItems] = useState(1);
  
  const addRow = () => {
    setItems((prev) => prev + 1)
  }

  return (
    <>
        <button onClick={addRow}>Add Row</button>
        <Grid container className='v-timeline-container'>
            {
              [...Array(items).keys()].map((key) => (
                <Grid xs={12} item className="v-timeline-item v-center v-border">
                  <p>{key + 1} row</p>
                </Grid>
              ))
            }
        </Grid>

    </>
  )
 }

export default ListItems

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.