Reputation: 461
i am working on an App that has an input field and a dropdown. The input field is for the event title and the dropdown has options for the type of event. When I click submit, I want to submit the value of both the event title and the selected dropdown value and render both as one list as I have in the images below.
But when I submit, only the event title is rendered. How can I include the event type too? Can I save the value of the selected dropdown in same array as the event title? Here's my code below:
EventListForm.jsx
import React from "react";
import { v4 as uuidv4 } from "uuid";
const EventListForm = ({
newEvent,
setNewEvent,
events,
setEventList,
}) => {
const handleInputChange = (event) => {
setNewEvent(event.target.value);
};
const submitEvent = (event) => {
event.preventDefault();
setEventList([...events, { id: uuidv4(), title: newEvent, type: newEvent}]);
};
return (
<form>
<div>
<input
type="text"
placeholder="Event title"
onChange={handleInputChange}
/>
</div>
<select onChange={handleInputChange}>
<option value="Birthday">Option 1</option> {" "}
<option value="Graduation">Option 2</option>
</select>
<div>
<button
type="submit"
onClick={submitEvent}
>
Submit
</button>
</div>
</form>
);
};
export default EventListForm;
EventList.jsx
import React from "react";
const EventList = ({ events, setEventList}) => {
return (
<div>
{events.map((event) => (
<li key={event.id}>
<input
type="text"
value={event.title}
value={event.type}
onChange={(event) => event.preventDefault()}
/>
</li>
))}
</div>
);
};
export default EventList;
Events.js
import React, {useState } from "react";
import EventListForm from "./EventForm";
import EventList from "./EventList";
const EventReminder = () => {
const [newEvent, setNewEvent] = useState("");
const [events, setEventList] = useState([]);
return (
<div>
<div>
<div>
<Header />
</div>
<div>
<EventListForm
newEvent={newEvent}
setNewEvent={setNewEvent}
events={events}
setEventList={setEventList}
/>
</div>
<div>
<EventList events={events} setEventList={setEventList} />
</div>
</div>
</div>
);
};
export default EventReminder;
Upvotes: 1
Views: 891
Reputation: 11427
There's some stuff to clean up here:
EventListForm
really should be local to that component. There is no need for it to be higher up, it overcomplicates and is over-scoping.onSubmit
instead, so it will work properly when pressing enter etc.import React from "react";
const EventListForm = ({
onSubmit
}) => {
const [title, setTitle] = useState("")
const [type, setType] = useState("")
return (
<form onSubmit={(e) => {
e.preventDefault()
onSubmit({title, type})
}>
<div>
<input
type="text"
placeholder="Event title"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</div>
<select onChange={(e) => setType(e.target.value)}>
<option selected={type == "Birthday"} value="Birthday">Option 1</option> {" "}
<option selected={type == "Graduation"} value="Graduation">Option 2</option>
</select>
<div>
<button
type="submit"
>
Submit
</button>
</div>
</form>
);
};
export default EventListForm;
import React, {useState } from "react";
import EventListForm from "./EventForm";
import EventList from "./EventList";
import { v4 as uuidv4 } from "uuid";
const EventReminder = () => {
const [events, setEventList] = useState([]);
return (
<div>
<div>
<div>
<Header />
</div>
<div>
<EventListForm
onSubmit={(event) => setEventList(prevEvents=> [...prevEvents, {id: uuidv4(), ...event}])}
/>
</div>
<div>
<EventList events={events} setEventList={setEventList} />
</div>
</div>
</div>
);
};
export default EventReminder;
import React from "react";
const EventList = ({ events}) => {
return (
<div>
{events.map((event) => (
<li key={event.id}>
<input
type="text"
value={event.title}
disabled
/>
<select disabled name="type">
<option value="Birthday" selected={event.type === "Birthday"}>Option 1</option>
<option value="Graduation" selected={event.type === "Graduation"}>Option 2</option>
</select>
</li>
))}
</div>
);
};
export default EventList;
Upvotes: 1
Reputation: 1021
This is happening to you because you are currently overriding the same state of newEvent
in each of the input fields, I corrected your code by changing the value of newEvent
to an object that contains a key for title
and for type
(note that I added a name attribute
in the inputs, and when submitting the form takes for each of the values the appropriate value from the state
const handleInputChange = (event) => {
setNewEvent({ [event.currentTarget.name]: event.target.value });
};
const submitEvent = (event) => {
event.preventDefault();
setEventList([...events, { id: uuidv4(), title: newEvent.title, type: newEvent.type}]);
};
return (
<form>
<div>
<input
type="text"
name="title"
placeholder="Event title"
onChange={handleInputChange}
/>
</div>
<select onChange={handleInputChange} name="type">
<option value="Birthday">Option 1</option> {" "}
<option value="Graduation">Option 2</option>
</select>
<div>
<button
type="submit"
onClick={submitEvent}
>
Submit
</button>
</div>
</form>
);
};
Upvotes: 0