添加新项目后,Apollo Graphql的更新状态

时间:2020-10-07 15:37:36

标签: reactjs graphql react-apollo apollo-client

在我的代码上,最初加载项目列表时显示“正在加载书籍”。我想要的是添加新项目时,列表组件将显示“正在添加书籍”。我的问题除了使用父级和子级传递“ 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

0 个答案:

没有答案