javascript - que - react graphql client
React Apollo-Hacer mĂșltiples consultas (6)
En mi humilde opinión, una de las soluciones más ingeniosas se describe en la implementación de Apollo Client React .
La idea básica es envolver sus consultas en componentes de consulta anidados. El uso de las funciones de cierre como elementos secundarios de los componentes hace que sea práctico delegar los resultados de una consulta en otra consulta, etc.
const QueryOne = gql`
query One {
one
}
`;
const QueryTwo = gql`
query Two {
two
}
`;
const NumbersWithData = () => (
<Query query={QueryOne}>
{({ loading: loadingOne, data: { one } }) => (
<Query query={QueryTwo}>
{({ loading: loadingTwo, data: { two }}) => {
if (loadingOne || loadingTwo) return <span>loading...</span>
return <h3>{one} is less than {two}</h3>
}}
</Query>
)}
</Query>
);
Tengo un archivo de consultas que se parece a esto:
import {gql} from ''react-apollo'';
const queries = {
getApps: gql`
{
apps {
id
name
}
}
`,
getSubjects: gql`
{
subjects {
id
name
}
}
`
};
export default queries;
Luego importo este archivo a mi componente React:
import React, {Component} from ''react''
import queries from ''./queries''
class Test extends Component {
...
}
export default graphql(queries.getSubjects)(graphql(queries.getApps)(Test));
Esto solo obtendrá datos para una de las consultas (getApps) y no para ambos. Si hago uno a la vez para que se vea así:
export default graphql(queries.getSubjects)(Test);
entonces funciona pero no tengo mi otra consulta. Sí, he probado ambos por separado y funcionan. ¿Cómo lo consigo para que ambas consultas aparezcan en mi props.data?
Estoy usando https://github.com/pedronauck/react-adopt para hacer esto. Es realmente sencillo y mantén limpio nuestro código.
Ejemplo simple:
import { adopt } from ''react-adopt'';
...
render() {
const Composed = adopt({
first: ({ render }) => <Query query={FIRST_QUERY}>{ render }</Query>,
second: ({ render }) => <Query query={SECOND_QUERY}>{ render }</Query>
});
return (
<Composed>
({ first, second }) => {
console.log(''first'', first)
console.log(''second'', second)
// validations (loading, error)
return (
<div>Your JSX</div>
)
}
</Composed>
)
}
...
Hay muchos ejemplos usando
const Composed = adopt({
first: <Query query={FIRST_QUERY} />,
second: <Query query={SECOND_QUERY} />
});
Tenga cuidado con el componente <Query>
, necesita un hijo, de lo contrario, tendrá el siguiente error:
Warning: Failed prop type: The prop children is marked as required in Query, but its value is undefined.
Para evitar la advertencia anterior, he encontrado una posible solución:
first: ({ render }) => <Query query={FIRST_QUERY}>{ render }</Query>
Espero que te ayude!
Mi forma preferida es usar la funcionalidad de compose
del cliente apollo ( docu ).
EDITAR: Si tiene más de una consulta, debe nombrarlas.
Así que en tu caso, podría verse así:
import React, {Component} from ''react''
import queries from ''./queries''
import { compose } from ''react-apollo'';
class Test extends Component {
...
render() {
...
console.log(this.props.subjectsQuery, this.props.appsQuery); // should show both
...
}
}
export default compose(
graphql(queries.getSubjects, {
name: "subjectsQuery"
}),
graphql(queries.getApps, {
name: "appsQuery"
}),
)(Test);
Otra forma de evitar esto es usar la opción de props
.
export default compose(
graphql(QUERY_2, {
props: ({ data }) => ({ ...data }),
}),
graphql(QUERY_1, {
props: ({ data }) => ({ ...data, myCustomAttribute: data.foo }),
}),
)(Component);
He encontrado que este enfoque es un poco mejor para mi caso de uso.
Aquí hay un enlace a los documentos: https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-props
Para Apollo 2.x : puede usar react-adopt
para componer las Consultas y Mutaciones en un solo nivel. (Esa biblioteca compondrá cualquier componente con elementos de representación, por ejemplo, la API de contexto de reacción).
Si no desea reutilizar cualquiera de esas consultas de forma independiente, ¿por qué no realizar una sola solicitud combinando ambas consultas en una sola?
const combinedQueries = gql`
{
apps {
id
name
}
subjects {
id
name
}
}
`
Y luego puedes usarlo en tu componente.
import React, {Component} from ''react''
import combinedQueries from ''./combinedQueries''
class Test extends Component {
...
render() {
...
if(!this.props.combinedQueries.loading) {
console.log(this.props.combinedQueries.apps);
console.log(this.props.combinedQueries.subjects);
}
...
}
}
export default graphql(combinedQueries, {name: ''combinedQueries''})(Test);