I am building a react on rails app. I have a button on the page that user can indicate whether they want to join a meet up or not. Clicking "join" button should create a rsvp relation between the current user and an event, and the button will be switched to "Leave", if user then click on the "Leave" button, this relationship will be deleted from the rails backend. After messing around my react component, my "Join" button doesn't trigger the "onSubmit" function, and the "Leave" button seems to return an error saying "submission form cancelled because form is not connected". I'd appreciated a lot if any one can help me clean my logic.
import React from 'react'
class EventsIndexContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
active: props.rsvp
}
this.toggleButton = this.toggleButton.bind(this)
this.handleRsvpSubmit = this.handleRsvpSubmit.bind(this)
this.handleRsvpDelete = this.handleRsvpDelete.bind(this)
}
toggleButton() {
this.setState({active: !this.state.active})
}
handleRsvpSubmit(event) {
event.preventDefault()
let formPayLoad = {
user_id: this.props.current_user.id,
event_id: this.props.selectedId
}
this.props.addRsvp(formPayLoad)
}
handleRsvpDelete() {
fetch(`/api/v1/rsvps/${this.props.selectedId}`, {
method: 'DELETE'}
)
}
render() {
let button
let joinButton =
<form onSubmit={this.handleRsvpSubmit}>
<button type="button" onClick={() => (this.props.handleSelect(),
this.toggleButton())}>Join</button>
</form>
let leaveButton =
<button type="button" onClick={() => (this.toggleButton(),
this.handleRsvpDelete)}>Leave</button>
button = this.state.active? leaveButton : joinButton
return(
<div>
<h4>{this.props.location} - {this.props.meal_type} at
{this.props.time}</h4>
<p>{this.props.group.name}</p>
{button}
<button>See who is going</button>
</div>
)
}
}
export default EventsIndexContainer
This is the parent container:
import React from 'react'
import GroupIndexContainer from './GroupIndexContainer'
import EventsIndexContainer from './EventsIndexContainer'
class MainContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
groups: [],
current_user: null,
events: [],
rsvps: [],
selectedId: null
}
this.fetchGroups = this.fetchGroups.bind(this)
this.fetchEvents = this.fetchEvents.bind(this)
this.handleSelect = this.handleSelect.bind(this)
this.addRsvp = this.addRsvp.bind(this)
this.fetchRsvps = this.fetchRsvps.bind(this)
}
componentDidMount() {
fetch('api/v1/users.json', {
credentials: 'same-origin',
method: "GET",
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
this.setState ({current_user: data.user})
})
.then(this.fetchGroups())
.then(this.fetchEvents())
.then(this.fetchRsvps())
}
fetchGroups() {
fetch('/api/v1/groups', {
credentials: 'same-origin',
method: "GET",
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
this.setState({groups: data.groups})
})
}
fetchEvents() {
fetch('/api/v1/events', {
credentials: 'same-origin',
method: "GET",
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
this.setState({events: data})
})
}
fetchRsvps() {
fetch('/api/v1/rsvps', {
credentials: 'same-origin',
method: "GET",
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
this.setState({rsvps: data.rsvps})
})
}
handleSelect(id) {
this.setState({selectedId: id})
}
addRsvp(formPayLoad) {
fetch('/api/v1/rsvps', {
method: 'POST',
credentials: 'same-origin',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify(formPayLoad)
})
}
render() {
let groups = this.state.groups.map((group) => {
return (
<GroupIndexContainer
key={group.id}
id={group.id}
name={group.name}
/>
)
})
let rsvp_ids = this.state.rsvps.map(rsvp => rsvp.event_id)
let events = this.state.events.map((event) => {
return(
<EventsIndexContainer
key={event.id}
id={event.id}
rsvp={rsvp_ids.some(rsvp_id => rsvp_id == event.id) ? true : false}
location={event.location}
meal_type={event.meal_type}
time={event.time}
group={event.group}
current_user={this.state.current_user}
user={event.user}
selectedId={this.state.selectedId}
addRsvp={this.addRsvp}
handleSelect={() => this.handleSelect(event.id)}
/>
)
})
return(
<div className="wrapper">
<div className="groups-index">
<h3>Your Groups:</h3>
{groups}
</div>
<div className="events-index">
<h3>What's happening today...</h3>
{events}
</div>
</div>
)
}
}
export default MainContainer