在我的代码上,最初加载项目列表时显示“正在加载书籍”。我想要的是添加新项目时,列表组件将显示“正在添加书籍”。我的问题除了使用父级和子级传递“ addBook”突变的加载状态外,还有更好的方法吗?我下面的代码运行良好,但是想知道apollo客户端是否有更好的解决方案。
这是我的代码:
应用程序(更好的组件)
import React, { useState } from "react"
import BookList from "./components/BookList"
import AddBook from "./components/AddBook"
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client"
const client = new ApolloClient({
uri: "http://localhost:4000/graphql",
cache: new InMemoryCache(),
})
function App() {
const [addBookLoadingStatus, setAddBookLoadingStatus] = useState(false)
const setAddBookLoading = (addBookLoadingStatus) => {
setAddBookLoadingStatus(addBookLoadingStatus)
}
return (
<ApolloProvider client={client}>
<div id="main">
<h1>Reading List</h1>
<BookList addBookLoadingStatus={addBookLoadingStatus} />
<AddBook setAddBookLoading={setAddBookLoading} />
</div>
</ApolloProvider>
)
}
export default App
BookList(子组件)
import React from "react"
import { useQuery, gql } from "@apollo/client"
import { GET_BOOK } from "../queries/queries"
function BookList(props) {
const { addBookLoadingStatus } = props
const { loading, error, data } = useQuery(GET_BOOK)
if (loading) return <h4>Loading books...</h4>
if (addBookLoadingStatus) return <h4>Adding books...</h4>
if (error) return `Error! ${error.message}`
return (
<div>
<ul id="book-list">
{data.books.map((book) => (
<li key={book.id}>{book.name}</li>
))}
</ul>
</div>
)
}
export default BookList
AddBook(子组件)
import React, { useState, useCallback } from "react"
import { useQuery, useMutation } from "@apollo/client"
import { GET_AUTHOR, ADD_BOOK, GET_BOOK } from "../queries/queries"
function AddBook(props) {
const { setAddBookLoading } = props
const [book, setBook] = useState({
name: "",
genre: "",
authorId: "",
})
const { loading, error, data } = useQuery(GET_AUTHOR)
const [addBook, { loading: addBookLoading, data: addBookData, error: addBookError }] = useMutation(ADD_BOOK, {
refetchQueries: [{ query: GET_BOOK }],
awaitRefetchQueries: true,
})
setAddBookLoading(addBookLoading)
const displayAuthors = () => {
if (loading) {
return <option disabled>Loading Authors...</option>
} else {
return data.authors.map((author) => {
return (
<option key={author.id} value={author.id}>
{author.name}
</option>
)
})
}
}
if (error) return `Error! ${error.message}`
const handleAdd = () => {}
const submitForm = (e) => {
e.preventDefault()
addBook({ variables: { name: book.name, genre: book.genre, authorId: book.authorId } })
setBook({
name: "",
genre: "",
authorId: "",
})
}
return (
<div>
<form id="add-book" onSubmit={submitForm}>
<div className="field">
<label>Book name:</label>
<input type="text" onChange={(e) => setBook({ ...book, name: e.target.value })} />
</div>
<div className="field">
<label>Genre:</label>
<input type="text" onChange={(e) => setBook({ ...book, genre: e.target.value })} />
</div>
<div className="field">
<label>Author:</label>
<select onChange={(e) => setBook({ ...book, authorId: e.target.value })}>
<option>Select author</option>
{displayAuthors()}
</select>
</div>
<button>+</button>
</form>
{addBookError && <p>Error :( Please try again</p>}
</div>
)
}
export default AddBook