#reactjs #graphql
Вопрос:
В настоящее время я следую учебнику по GraphQL от netninja на you tube (я на уроке № 35). В инструкциях по реагированию немного не хватает данных, поэтому мне пришлось прочитать последние документы, чтобы заставить некоторые части работать. Однако сейчас я застрял на несколько прямолинейной проблеме. У меня есть запрос, который подключается к моему серверу GraphQL и извлекает данные, и я хочу вывести данные. Я могу вывести объект данных на консоль, но когда я пытаюсь получить доступ к различным частям информации, я получаю «неопределенную» ошибку:
Ссылка на исходный код, созданный инструктором на github: https://github.com/iamshaunjp/graphql-playlist/blob/lesson-35/client/src/components/BookDetails.js
Вот мой вопрос:
const getBookQuery = gql`
query($id: ID){
book(id: $id) {
id
name
genre
author {
id
name
age
books {
name
id
}
}
}
}
`;
И вот мой код реакции:
import { getBookQuery } from '../queries/queries';
import { graphql, useQuery } from "@apollo/client";
const displayBookDetails = (loading, data) =>{
if(loading){
return( <p>Loading book details</p> );
}else{
return(
<div>
<h2>{ data.name }</h2>
<p>{ data.genre }</p>
<p>{ data.author.name }</p>
<p>All books by this author:</p>
<ul className="other-books">
{ data.author.books.map(item => {
return <li key={item.id}>{ item.name }</li>
})}
</ul>
</div>
);
}
}
function BookDetails({ bookid }) {
const { loading, error, data } = useQuery(getBookQuery, { variables: { id: bookid }});
console.log( bookid );
console.log( data );
return (
displayBookDetails(loading, data)
);
}
export default BookDetails;
Заранее спасибо.
Обновление: Вот ошибка из консоли:
[GraphQL error]: Message: Variable "$id" got invalid value { bookid: "60f6cab81c87353e5be8c513" }; ID cannot represent value: { bookid: "60f6cab81c87353e5be8c513" }, Location: [object Object], Path: undefined
Обновление 2:
Код, который вызывает BookDetails и передает bookid
import { useQuery } from "@apollo/client";
import { useState } from "react";
import {getBooks} from '../queries/queries';
//Components
import BookDetails from './BookDetails';
function BookList() {
const [selected, setSelected] = useState(null);
const bookid = '';
const {loading, error, data} = useQuery(getBooks);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error </p>;
console.log(data);
console.log('selected:' selected);
return (
<div>
<ul id="book-list">
{data.books.map(book => (
<li key={book.id} onClick={(e) => setSelected(book.id)}>{book.name}</li>
))}
</ul>
<BookDetails bookid={selected}/> {/* <--- Here is where the bookid is passed to bookdetails component */}
</div>
);
}
export default BookList;
Комментарии:
1. поместите
console.log
displayBookDetails
, в соответствующие части/условия — условия предназначены для sth — переосмыслите их роль во времени (повторите изменения), прочитайте документы apollo еще раз2. если
console.log( "bookid: ", bookid );
регистрирует объект (должен быть строкой), то плохаяbookid
поддержка/значение передаются<BookDetails/>
компоненту3. Я думаю, что вы правы, и то, как я сдал букид, плохо. Я добавил код, который вызывает компонент Bookdetail выше.
4. код выглядит хорошо … но ничего о результатах журнала, структурах данных [1-го запроса], теле сетевого запроса (инструменты разработки), переданных реквизитах (инструменты разработки react) …
{selected amp;amp; <BookDetails ...>}
, … просто позвониdisplayBookDetails()
, вместо того, чтобыreturn ( displayBookDetails
Ответ №1:
Похоже, код, который вызывает / отображает BookDetails
, отсутствует.
И похоже, что вы визуализируете его как <BookDetails bookid={{bookid: 'id1'}} />
вместо <BookDetails bookid="id1" />
Ответ №2:
После долгих поисков и безуспешного чтения кто-то, к счастью, прокомментировал оригинальное видео на YouTube с ответом. Вот рабочий код для всех, кто может столкнуться с этим в будущем;
import { useQuery } from '@apollo/client';
import { getBookQuery } from '../queries/queries'
const displayBookDetails = (loading, data, error) => {
if (loading) return <p>loading...</p>
if (error) return <p>Something went wrong..</p>
if (data.book) {
return (
<div>
<h2>{data.book.name}</h2>
<p>{data.book.genre}</p>
<p>{data.book.author.name}</p>
<p>All the books by the author: </p>
<ul className="other-books">
{data.book.author.books.map(item =>{
return<li key={item.id}>{item.name}</li>
})
}
</ul>
</div>
)
}else{
return(
<div>
No data to display..
</div>
)
}
}
function BookDetails(props) {
const { loading, data, error } = useQuery(getBookQuery, {
variables: {
id: props.bookId
}
});
// console.log(data)
return (
<div id="book-details">
<p>OutPut here</p>
{displayBookDetails(loading, data, error)}
</div>
)
}
export default BookDetails;