2
votes

I've created a react app driven by Apollo client and graphQL.
My schema is defined so the expected result is an array of objects ([{name:"metric 1", type:"type A"},{name:"metric 2", type:"type B"}])

On my jsx file I have the following query defined:

query metrics($id: String!) {
  metrics(id: $id) {
    type
    name
  }
}`;

I've wrapped the component with Apollo HOC like so:

export default graphql(metricsQuery, {
  options: (ownProps) => {
    return {
      variables: {id: ownProps.id}
    }
  }
})(MetricsComp);

The Apollo client works fine and returns the expected list on the props in the render method.


I want to let the user manipulate the results on the client (edit / remove a metric from the list, no mutation to the actual data on the server is needed). However since the results are on the component props, I have to move them to the state in order to be able to mutate. How can I move the results to the state without causing an infinite loop?

3

3 Answers

1
votes

If apollo works anything like relay in this matter, you could try using componentWillReceiveProps:

class ... extends Component {

  componentWillReceiveProps({ metrics }) {
    if(metrics) {
      this.setState({
        metrics,
      })
    }  
  }
}

something like this.

1
votes

componentWillReceiveProps will be deprecated soon (reference link)

If you are using React 16 then you can do this:

class DemoClass extends Component {
  state = {
    demoState: null // This is the state value which is dependent on props
  }

  render() {
    ...
  }
}

DemoClass.propTypes = {
  demoProp: PropTypes.any.isRequired,  // This prop will be set as state of the component (demoState)
}

DemoClass.getDerivedStateFromProps = (props, state) => {
  if (state.demoState === null && props.demoProp) {
    return {
      demoState: props.demoProp,
    }
  }
  return null;
}

You can learn more about this by reading these: link1, link2

0
votes

you can use this:

import {useState} from 'react';
import {useQuery} from '@apollo/client';

const [metrics,setMetrics]=useState();

useQuery(metricsQuery,{
    variables:{id: ownProps.id},
    onCompleted({metrics}){
        setMetrics(metrics);
    }
});