Noob
Noob

Reputation: 156

React map method Render Input dynamically change value separate fields

I am got a loop data Array that contains more than 100 data and I am used map method to render it that are already defined the user can update only for the specific field have id and unique id I now need to be able to edit/submit them uniquely separate fields.All fields should be some default. At the moment, I haven't figured out how to differentiate them onChange causing the state to be the same on ALL fields. I need each field to update separately with its unique data and I am using react hooks Input Forms, rendered by the map. These are the forms I want unique update fields.

Please Give Any Idea that will helpful to implement or suggestion how to approach this I am new to react please help us

Thanks for Help

codesandoxLink:https://codesandbox.io/s/react-week-date-view-r3mvj?file=/src/App.js

Upvotes: 0

Views: 13914

Answers (2)

akhtarvahid
akhtarvahid

Reputation: 9769

Code changed to update particular field in loop. if you want to other field to update you can follow the same.

pass ID and event to function

<input
    name="roomRent"
    type="text"
    value={roomData.room}
    className={classes.input}
    onChange={(e) => handleroom(e, i)}
 />

function to update particulat field value

  const handleroom = (e, id) => {
    const { value } = e.target;
    setRooms((room) =>
      room?.map((list, index) =>
        index === id ? { ...list, room: value } : list
      )
    );
  };

Improved code

export default function RoomListView() {
  const classes = useStyles();
  const [roomes, setRooms] = useState([...rooms]);

  const handleroom = (e, id) => {
    const { value } = e.target;
    setRooms((room) =>
      room?.map((list, index) =>
        index === id ? { ...list, room: value } : list
      )
    );
  };

  return (
    <>
      <div className={classes.root}>
        <Paper className={classes.paper} variant="outlined" elevation={0}>
          <div className={classes.layout}>
            <div className={classes.main1}>
              <Grid container>
                <Grid item sm={3}>
                  <div className={classes.roomType}>
                    <h4 className={classes.roomTypeContent}>Room Rate</h4>
                  </div>
                </Grid>
                <Grid item sm={9}>
                  <div className={classes.Roomcalendar}>
                    {roomes.map((roomData, i) => {
                      return (
                        <>
                          <div className={classes.Roomview}>
                            <div
                              key={roomData.id}
                              className={classes.roomavailable}
                            >
                              <input
                                name="roomRent"
                                type="text"
                                value={roomData.room}
                                className={classes.input}
                                onChange={(e) => handleroom(e, i)}
                              />
                            </div>
                            <div className={classes.roomSold}>
                              <p>{roomData.sold} Sold</p>
                            </div>
                          </div>
                        </>
                      );
                    })}
                  </div>
                </Grid>
              </Grid>
            </div>
          </div>
        </Paper>
      </div>
    </>
  );
}

Live working code

Upvotes: 0

Giovanni Esposito
Giovanni Esposito

Reputation: 11156

Here a working solution (I edited your codesandbox). Basically what I have done is:

  1. initialize roomRent with rooms:

     const [roomRent, setRoomRent] = useState(rooms);
    
  2. use map on roomRent:

     roomRent.map((roomData) => {
                       return (
                         <>
                           <div className={classes.Roomview}>
                             <div
                               key={roomData.id}
                               className={classes.roomavailable}
                             >
                               <input
                                 name="roomRent"
                                 type="text"
                                 value={roomData.room}
                                 className={classes.input}
                                 onChange={(e) => handleroom(e, roomData.id)}
                               />
                             </div>
                             <div className={classes.roomSold}>
                               <p>{roomData.sold} Sold</p>
                             </div>
                           </div>
                         </>
                       );
                     })
    

Note that now handleroom has 2 inputs: e and roomData.id;

  1. changed handleroom function in this way:

     const handleroom = (e, id) => {
         var result = [...roomRent]; //<- copy roomRent into result
         result = result.map((x) => { //<- use map on result to find element to update using id
           if (x.id === id) x.room = e.target.value;
           return x;
         });
         setRoomRent(result); //<- update roomRent with value edited
       };
    

Upvotes: 5

Related Questions