对应内容:#19 Cancel Bookings | Build a Complete App with GraphQL, Node.js, MongoDB and React.js
主要内容:
- 完善Booking 页面,添加取消订阅功能
- 修改snipper 工作逻辑,改为Fixed定位
1 完善Booking 页面,添加取消订阅功能
创建 BookingList.js
import React from 'react';
const BookingList = ({bookings, cancelBooking}) => {
if (bookings.length === 0) {
return <h1 style={{textAlign: "center"}}>Empty</h1>
}
return (
<ul className="eventList">
{
bookings.map(booking => {
return (
<BookingItem
booking={booking}
cancelBooking={cancelBooking}
key={booking._id}
/>
);
})
}
</ul>
)
};
const BookingItem = ({ booking, cancelBooking }) => {
return (
<li className="eventlist__item" key={booking._id}>
<span>
{booking.event.title} - {booking.createdAt}
</span>
<button onClick={cancelBooking.bind(null, booking._id)}>
DELETE
</button>
</li>
);
};
export default BookingList;
在booking.js 中添加取消函数
import React, { Component } from 'react';
import AuthContext from '../context/auth-context';
import Snipper from '../components/Snipper/Snipper';
import BookingList from '../components/BookingList/BookingList';
class BookingsPage extends Component {
state = {
isLoading: false,
bookings: []
}
static contextType = AuthContext;
componentDidMount () {
this.fetchBookings();
}
fetchBookings = () => {
...
};
cancelBooking = (bookingId) => {
this.setState({
isLoading: true
});
const queryBody = {
query: `
mutation {
cancelBooking(bookingId: "${bookingId}") {
_id
}
}
`
};
fetch("http://localhost:3030/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + this.context.token
},
body: JSON.stringify(queryBody)
})
.then(response => {
if (response.status !== 200 && response.status !== 201) {
throw new Error("request failed!");
}
return response.json();
})
.then(() => {
let idx = 0;
for (let book of this.state.bookings) {
if (book._id === bookingId) {
this.setState({
bookings: this.state.bookings.slice(0, idx).concat(this.state.bookings.slice(idx + 1))
})
break;
}
idx += 1;
}
this.setState({
isLoading: false
});
})
};
render() {
return (
<React.Fragment>
<h1>The booking Page</h1>
{
this.state.isLoading && <Snipper />
}
<BookingList bookings={this.state.bookings} cancelBooking={this.cancelBooking}></BookingList>
</React.Fragment>
);
}
}
export default BookingsPage;
2 修改snipper 工作逻辑,改为Fixed定位
.lds-spinner {
color: official;
display: block;
position: absolute;
width: 80px;
height: 80px;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
当元素有宽高的时候,且为absolute或fixed布局时,给上下左右的距离置为0时,可以达到水平垂直居中的目的,margin必须为auto。