Я получаю эту ошибку, пытаясь использовать response-apollo от публичного graphql api .
Недопустимый вызов ловушки. Хуки могут быть вызваны только внутри тела функционального компонента. Это может произойти по одной из следующих причин:
- У вас могут быть несовпадающие версии React и средства визуализации (например, React DOM)
- Возможно, вы нарушаете правила хуков
- Возможно, в одном приложении может быть несколько копий React
Я прочитал Реакция документации , и я уверен, что проблема в том,ни одна из этих трех причин.
Это простой проект, использующий create-react-app
. Обе версии react
и react-dom
16.10.2
.
app.js:
import React, {useState} from 'react';
import { Query } from "react-apollo";
import { gql } from "apollo-boost";
const query = gql`
{
countries {
name
code
}
}
`;
function App() {
const [country, setCountry] = useState('US');
const onCountryChange = event => {
setCountry(event.target.value);
};
return (
<div className="App">
<Query query={query}>
{result => {
if (result.loading) return <p>Loading...</p>;
if (result.error) return <p>{result.error.message}</p>;
return (
<select value={country} onChange={onCountryChange}>
{result.data.countries.map(country => (
<option key={country.code} value={country.code}>
{country.name}
</option>
))}
</select>
);
}}
</Query>
</div>
);
}
export default App;
index.js:
import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import App from "./app";
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from "react-apollo";
const client = new ApolloClient({
uri: 'https://countries.trevorblades.com'
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById("root")
);
Я новичокв GraphQl и Apollo и не знаю, что может быть причиной этой ошибки.
Обновление
Как предложил @Joseph, я извлек компонент из приложения и использовал useQuery
,и теперь код выглядит так:
Select.js:
import React, {useState} from 'react';
function Select(props) {
const [country, setCountry] = useState('US');
const onCountryChange = event => {
setCountry(event.target.value); // already called within the function component
};
return (
<select value={country} onChange={onCountryChange}>
{props.countries.map(country => (
<option key={country.code} value={country.code}>
{country.name}
</option>
))}
</select>
);
}
export default Select;
app.js:
import React from 'react';
import { Query } from "react-apollo";
import { gql } from "apollo-boost";
import { useQuery } from '@apollo/react-hooks';
import Select from './select';
const query = gql`
{
countries {
name
code
}
}
`;
function App() {
const { loading, error, data } = useQuery(query);
return (
<div className="App">
<>
{loading && <p>Loading...</p>}
{error && <p>{error.message}</p>}
<Select countries={data.countries} />
</>
</div>
);
}
export default App;
Без изменений в index.js
, но я все ещеполучить ту же ошибку.
Обновление 2:
Мне не хватало установки @apollo/react-hooks
, но когда я установил ее, я получил новую ошибку:
Не удалосьне найти "клиента" в контексте или передан в качестве опции. Оберните корневой компонент в или передайте экземпляр ApolloClient через параметры.
Обновление 3:
Это долго, но я импортировал ApolloProvider
из @apollo/react-hooks
в index.js
, чтобы исправить последнюю проблему:
import { ApolloProvider } from "@apollo/react-hooks";
И теперь я получаю
TypeError: данные не определены
В этой строкеapp.js
:
<>
{loading && <p>Loading...</p>}
{error && <p>{error.message}</p>}
<Select countries={data.countries} /> // <= This line causes error
</>