Get the value of dynamically created same child component

29 Views Asked by At

I have created a child component of a MUI TextFiled inside a MUI card.

import * as React from 'react';
import Box from '@mui/material/Box';
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import TextField from '@mui/material/TextField';

const bull = (
  <Box
    component="span"
    sx={{ display: 'inline-block', mx: '2px', transform: 'scale(0.8)' }}
  >
  </Box>
);

export default function BasicCard({ dataObj }) {
 const [value, setValue] = React.useState(0);
 const location = useLocation();

 React.useEffect(() => {
   setValue(dataObj.weight);
 }, [location, dataObj])

  return (
    <Card sx={{ minWidth: 75}}>
      <CardContent>
        <TextField type="number" value={value} />
      </CardContent>
    </Card>
  );
}

Based on the existing below data I have dynamically rendered the textfields. So basically i have called the same child component 3 times for each data in the object

[
{ "metric": "AAA", "weight": 10},
{ "metric": "BB", "weight": 20},
{ "metric": "CCC", "weight": 30},
]

If we manually change the values of the TextField, how to get the value of all three data (changed or not changed) on clicking a button in the parent component

Any help is much appreciated

Thanks,

1

There are 1 best solutions below

1
Bharti Sharma On BEST ANSWER

You don't need to call your child component 3 time in your parent component. You can use map for this and also for getting value in parent component you need to create initial state in parent component and then need to pass related props to child component. Please check below example:-

import * as React from 'react';
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import TextField from '@mui/material/TextField';

function BasicCard({ dataObj, value, onChange }) {
  const handleChange = (event) => {
    onChange(event.target.value, dataObj.metric);
  };

  return (
    <Card sx={{ minWidth: 75}}>
      <CardContent>
        <TextField type="number" value={value} onChange={handleChange} />
      </CardContent>
    </Card>
  );
}


export default function ParentComponent() {
  const initialData = [
    { "metric": "AAA", "weight": 10},
    { "metric": "BB", "weight": 20},
    { "metric": "CCC", "weight": 30},
  ];

  const [data, setData] = React.useState(initialData);

  const handleCardChange = (newValue, metric) => {
    setData(prevData => {
      return prevData.map(item => {
        if (item.metric === metric) {
          return { ...item, weight: newValue };
        }
        return item;
      });
    });
  };

  const handleClick = () => {
    console.log(data);
  };

  return (
    <div>
      {data.map((item) => (
        <BasicCard
          key={item.metric}
          dataObj={item}
          value={item.weight}
          onChange={handleCardChange}
        />
      ))}
      <button onClick={handleClick}>Get Values</button>
    </div>
  );
}

Here we are passing onChange and item to child component and there is one console statement in handleClick function so you can see values for all 3 fields in console by inspecting in your browser.

Let me know if it works for you or not.