Skip to content
Advertisement

How to create new components on every button click in “React”

So I want when the user clicks on the button, be able to create new CatagoryField Component that I made. When I place the component in a function and call it it will only create the component once. I will appreciate some help. I’m confused about how should I implement this?

App components

import React, { useState } from "react";
import {
  Accordion,
  AccordionSummary,
  Chip,
  Button,
  IconButton,
  Autocomplete,
  TextField,
} from "@mui/material";
import { Grid } from "@mui/material";
import SearchBar from "material-ui-search-bar";
import DeleteIcon from "@mui/icons-material/Delete";
import ExpandMoreOutlinedIcon from "@mui/icons-material/ExpandMoreOutlined";
import AddCircleOutlineOutlinedIcon from "@mui/icons-material/AddCircleOutlineOutlined";
import HelpIcon from "@mui/icons-material/Help";
import HistoryToggleOffIcon from "@mui/icons-material/HistoryToggleOff";
import AllMembers from "./components/common/main/allMembers";
import CatagoryField from "./components/common/main/catagoryField";

const autoCompleteOptions = [
  { title: "A", year: 1994 },
  { title: "B", year: 1972 },
  { title: "C", year: 1974 },
  { title: "D", year: 2008 },
  { title: "E", year: 1957 },
  { title: "F", year: 1993 },
  { title: "G", year: 1994 },
];

const App = () => {
  const [value, setValue] = useState();
  const [element, setElement] = useState(0);

  const doSomethingWith = () => {
    return null;
  };

    let i = 0;
  const creator = () => {
    while (i < element) {
      i++;
      return (
        <CatagoryField
          catagoryName="خدماتی"
          react="از آنها چیزی میخریم"
          createdBy="سیستم"
          disable={false}
        />
      );
    }
  };

  console.log(element);
  return (
    <>
      <div style={{ margin: "4rem 1rem" }}>
        <Accordion>
          <AccordionSummary
            sx={{ height: "65px" }}
            aria-controls="panel1a-content"
          >
            <Grid
              container
              direction="row"
              justifyContent="space-between"
              alignItems="center"
            >
              <Grid item>
                <IconButton className="chevron__icon">
                  <ExpandMoreOutlinedIcon />
                </IconButton>
                <span className="users__catagory"> دسته بندی کاربران</span>
              </Grid>
              <Grid item>
                <IconButton>
                  <HistoryToggleOffIcon />
                </IconButton>
                <IconButton>
                  <HelpIcon className="help" />
                </IconButton>
                <span className="version">4.3.2</span>
              </Grid>
            </Grid>
          </AccordionSummary>
          <AccordionSummary
            sx={{
              height: "65px",
              padding: "30px",
              background: "#E6E6E6",
              cursor: "default !important",
            }}
            aria-controls="panel1a-content"
          >
            <Grid
              container
              direction="row"
              alignItems="center"
              sx={{ display: "relative" }}
            >
              <Grid item>
                <Button
                  variant="outlined"
                  sx={{ height: "50px" }}
                  size="medium"
                  onClick={() => setElement(element + 1)}
                  endIcon={
                    <AddCircleOutlineOutlinedIcon
                      sx={{ marginRight: "10px" }}
                    />
                  }
                >
                  افزودن دسته جدید
                </Button>
              </Grid>
              <Grid sx={{ width: "207px" }} item>
                <SearchBar
                  className="search__holder"
                  placeholder="جستجو..."
                  value={value}
                  style={{ width: "207px", height: "45px" }}
                  onChange={(newValue) => setValue(newValue)}
                  onRequestSearch={() => doSomethingWith()}
                />
              </Grid>
              <Grid className="sort__field" item>
                <Autocomplete
                  sx={{
                    width: "207px !important",
                    padding: "0 !important",
                    backgroundColor: "white !important",
                  }}
                  options={autoCompleteOptions}
                  getOptionLabel={(option) => option.title}
                  renderTags={(value, getTagProps) =>
                    value.map((option, index) => (
                      <Chip
                        variant="outlined"
                        label={option.title}
                        {...getTagProps({ index })}
                      />
                    ))
                  }
                  renderInput={(params) => (
                    <TextField
                      {...params}
                      variant="filled"
                      sx={{
                        width: "207px !important",
                        padding: "0 !important",
                        background: "white !important",
                      }}
                      placeholder="مرتب سازی..."
                    />
                  )}
                />
              </Grid>
              <Grid item>
                <IconButton sx={{ margin: "0 5px" }}>
                  <DeleteIcon />
                </IconButton>
              </Grid>
              <Grid item className="last__edit">
                <Grid item>
                  <span>
                    آخرین ویرایش:
                    <a className="last_Modified" href="#">
                      سیستم
                    </a>
                  </span>
                  <span>1405/12/24 23:59 </span>
                </Grid>
              </Grid>
            </Grid>
          </AccordionSummary>
          <AllMembers />
          <CatagoryField
            catagoryName="اپراتور سیستم"
            react="اپراتور سیستم"
            createdBy="سیستم"
          />
          <CatagoryField
            catagoryName="مشتریان"
            react="به آنها چیزی فروخته ایم"
            createdBy="سیستم"
          />
          <CatagoryField
            catagoryName="خدماتی"
            react="از آنها چیزی میخریم"
            createdBy="سیستم"
            disable={false}
          />
          {creator()}
        </Accordion>
      </div>
    </>
  );
};

export default App;

Advertisement

Answer

The best way in order to achieve the solution is to use a state with useMemo.and the problem with your code is that the creator acts as a function and it will only execute once try this.

import {useMemo} from 'react';
const App = () => {
const [elements , setElements] = useState(0);
 const creator = useMemo(() => {
   return (
       <>
         {Array(elements).fill(elements).map((item , index) => (
            <CategoryField
              key={`cat-${index}`} // key is need when mapping! it is not props
              catagoryName="خدماتی"
              react="از آنها چیزی میخریم"
              createdBy="سیستم"
              disable={false}
         
             />
         ))}
       </>
  )
 },[elements]);//render when elements change

  return (
<>
  <div style={{ margin: "4rem 1rem" }}>
    <Accordion>
      <AccordionSummary
        sx={{ height: "65px" }}
        aria-controls="panel1a-content"
      >
        <Grid
          container
          direction="row"
          justifyContent="space-between"
          alignItems="center"
        >
          <Grid item>
            <IconButton className="chevron__icon">
              <ExpandMoreOutlinedIcon />
            </IconButton>
            <span className="users__catagory"> دسته بندی کاربران</span>
          </Grid>
          <Grid item>
            <IconButton>
              <HistoryToggleOffIcon />
            </IconButton>
            <IconButton>
              <HelpIcon className="help" />
            </IconButton>
            <span className="version">4.3.2</span>
          </Grid>
        </Grid>
      </AccordionSummary>
      <AccordionSummary
        sx={{
          height: "65px",
          padding: "30px",
          background: "#E6E6E6",
          cursor: "default !important",
        }}
        aria-controls="panel1a-content"
      >
        <Grid
          container
          direction="row"
          alignItems="center"
          sx={{ display: "relative" }}
        >
          <Grid item>
            <Button
              variant="outlined"
              sx={{ height: "50px" }}
              size="medium"
              onClick={() => setElements(elements + 1)}
              endIcon={
                <AddCircleOutlineOutlinedIcon
                  sx={{ marginRight: "10px" }}
                />
              }
            >
              افزودن دسته جدید
            </Button>
          </Grid>
          <Grid sx={{ width: "207px" }} item>
            <SearchBar
              className="search__holder"
              placeholder="جستجو..."
              value={value}
              style={{ width: "207px", height: "45px" }}
              onChange={(newValue) => setValue(newValue)}
              onRequestSearch={() => doSomethingWith()}
            />
          </Grid>
          <Grid className="sort__field" item>
            <Autocomplete
              sx={{
                width: "207px !important",
                padding: "0 !important",
                backgroundColor: "white !important",
              }}
              options={autoCompleteOptions}
              getOptionLabel={(option) => option.title}
              renderTags={(value, getTagProps) =>
                value.map((option, index) => (
                  <Chip
                   key={`chip-${index}`}
                    variant="outlined"
                    label={option.title}
                    {...getTagProps({ index })}
                  />
                ))
              }
              renderInput={(params) => (
                <TextField
                  {...params}
                  variant="filled"
                  sx={{
                    width: "207px !important",
                    padding: "0 !important",
                    background: "white !important",
                  }}
                  placeholder="مرتب سازی..."
                />
              )}
            />
          </Grid>
          <Grid item>
            <IconButton sx={{ margin: "0 5px" }}>
              <DeleteIcon />
            </IconButton>
          </Grid>
          <Grid item className="last__edit">
            <Grid item>
              <span>
                آخرین ویرایش:
                <a className="last_Modified" href="#">
                  سیستم
                </a>
              </span>
              <span>1405/12/24 23:59 </span>
            </Grid>
          </Grid>
        </Grid>
      </AccordionSummary>
      <AllMembers />
      <CatagoryField
        catagoryName="اپراتور سیستم"
        react="اپراتور سیستم"
        createdBy="سیستم"
      />
      <CatagoryField
        catagoryName="مشتریان"
        react="به آنها چیزی فروخته ایم"
        createdBy="سیستم"
      />
      <CatagoryField
        catagoryName="خدماتی"
        react="از آنها چیزی میخریم"
        createdBy="سیستم"
        disable={false}
      />
      {creator}
    </Accordion>
  </div>
 </>
);

}
export default App;
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement