Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Apollo: Dynamically update GraphQL query from Component state

I have a component that shows results from a GraphQL query using the react-apollo decorator syntax. The query accepts a parameter, which I want to set dynamically based on component state.

Consider the following simplified example:

import * as React from ‘react’;
import { graphql } from ‘react-apollo’;
import gql from ‘graphql-tag’;

const myQuery = gql`
    query($active: boolean!) {
        items(active: $active) {

        }
    }
`;

@graphql(myQuery)
class MyQueryResultComponent extends React.Component {
    public render() {
        return <div>
            <input type=“checkbox” /* other attributes and bindings */ />
            {this.props.data.items}
        <div>;
    }
}

When the checkbox is clicked I want to resubmit the query, dynamically setting the active attribute in myQuery, based on the state of the checkbox. I've omitted the handler and bindings of the checkbox for brevity, but how can I cause the query to be re-submitted upon a state change?

like image 781
duncanhall Avatar asked Jun 28 '17 16:06

duncanhall


1 Answers

Create a new component which will have the prop active passed from a parent component.

This procedure is very well explained in react-apollo docs in section: Computing from props

Based on your example and your requirements, I made a demo which is hosted on codesandbox and uses GraphQL API.

Demo: https://codesandbox.io/embed/PNnjBPmV2

Data.js

import React from 'react';
import PropTypes from 'prop-types';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

const Data = ({ data }) =>
  <div>
    <h2>Data</h2>
    <pre style={{ textAlign: 'left' }}>
      {JSON.stringify(data, undefined, 2)}
    </pre>
  </div>;

Data.propTypes = {
  active: PropTypes.bool.isRequired,
};

const query = gql`
  query SearchAuthor($id: Int!) {
    author(id: $id) {
      id
      firstName
      lastName
    }
  }
`;

export default graphql(query, {
  options(ownProps) {
    return {
      variables: {
        // This is the place where you can 
        // access your component's props and provide
        // variables for your query
        id: ownProps.active ? 1 : 2,
      },
    };
  },
})(Data);

App.js

import React, { Component } from 'react';
import Data from './Data';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      active: false,
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange() {
    this.setState(prevState => ({
      active: !prevState.active,
    }));
  }

  render() {
    const { active } = this.state;

    return (
      <div>
        <h1>App</h1>
        <div>
          <label>
            <input
              type="checkbox"
              checked={active}
              onChange={this.handleChange}
            />
            If selected, fetch author <strong>id: 1</strong>
          </label>
        </div>
        <Data active={active} />
      </div>
    );
  }
}

export default App;
like image 182
Dawid Karabin Avatar answered Nov 18 '22 08:11

Dawid Karabin