title: React functional component not updating on setState from parent component
body: <p>My React component uses apollo to fetch data via graphql</p>
  <pre><code>class PopUpForm extends React.Component {
  
    constructor () {
      super()
      this.state = {
        shoptitle: &quot;UpdateMe&quot;,
        popupbodyDesc: &quot;UpdateMe&quot;
      }
    }
  
  render() 
  {
      return (
          &lt;&gt;
          &lt;Query query={STORE_META}&gt;
            {({ data, loading, error, refetch }) =&gt; {
              
         
              if (loading) return &lt;div&gt;Loading…&lt;/div&gt;;
              if (error) return &lt;div&gt;{error.message}&lt;/div&gt;;
              if (!data) return (
                &lt;p&gt;Could not find metafields :(&lt;/p&gt;
              );
  
              console.log(data);
               //loop over data
                var loopedmetafields = data.shop.metafields.edges
                console.log(loopedmetafields)
                loopedmetafields.forEach(element =&gt; {
                  console.log(element.node.value)
                  if (element.node.value === &quot;ExtraShopDescription&quot;){
                    
                    this.setState({
                      shoptitle: element.node.value
                    });
                    console.log(this.state.shoptitle)
                  }
                  if (element.node.value === &quot;bodyDesc&quot;){
                     
                    this.setState({
                      popupbodyDesc: element.node.value
                    });
                    console.log(this.state.popupbodyDesc)
                  }
                });
              return (
                &lt;&gt;
                  &lt;AddTodo  mkey=&quot;ExtraShopDesc&quot; namespace=&quot;ExtraShopDescription&quot; desc={this.state.shoptitle} onUpdate={refetch} /&gt;
                  &lt;AddTodo  mkey=&quot;body&quot; namespace=&quot;bodyDesc&quot; desc={this.state.popupbodyDesc} onUpdate={refetch} /&gt;
                &lt;/&gt;
              );
          }}
          &lt;/Query&gt;
          &lt;/&gt;
      )
      }
  }
  
  export default PopUpForm
  </code></pre>
  <p>Frustratingly the functional component renders before the state is set from the query. Ideally the functional component would only render after this as I thought was baked into the apollo library but seems I was mistaken and it seems to execute synchronous rather than asynchronous</p>
  <p>As you can see I pass the props to the child component, in the child component I use these to show the current value that someone might amend</p>
  <p>The functional component is here</p>
  <pre><code> function AddTodo(props) {
  
  let input;
  const [desc, setDesc] = useState(props.desc);
  //console.log(desc)
  
  useEffect( () =&gt; {
    console.log('props updated');
    console.log(props)
  }, [props.desc])
  
  const [addTodo, { data, loading, error }] = useMutation(UPDATE_TEXT, {
      refetchQueries: [
          'STORE_META' // Query name
        ],
  });
  
  //console.log(data)
  if (loading) return 'Submitting...';
  if (error) return `Submission error! ${error.message}`;
  
  return (
    &lt;div&gt;
      &lt;form
        onSubmit={e =&gt; {
          console.log(input.value)
          setDesc(input.value)
          e.preventDefault();
          const newmetafields = {
              key: props.mkey,
              namespace: props.namespace,
              ownerId: &quot;gid://shopify/Shop/55595073672&quot;,
              type: &quot;single_line_text_field&quot;,
              value: input.value
          }
          addTodo({ variables: { metafields: newmetafields } });
          input.value = input.value
        }}
      &gt;
          &lt;p&gt;This field denotes the title of your pop-up&lt;/p&gt;
        &lt;input className=&quot;titleInput&quot; defaultValue={desc} 
          ref={node =&gt; {
            input = node;
          }}
        /&gt;
        &lt;button className=&quot;buttonClick&quot; type=&quot;submit&quot;&gt;Update&lt;/button&gt;
      &lt;/form&gt;
  
    &lt;/div&gt;
  );
  </code></pre>
  <p>}</p>
  <p>Now I need this component to update when the setState is called on PopUpForm</p>
  <p>Another stack overflow answer <a href="https://stackoverflow.com/questions/41233458/react-child-component-not-updating-after-parent-state-change">here</a> gives me some clues</p>
  <blockquote>
  <p>Passing the intial state to a component as a prop is an anti-pattern
  because the getInitialState (in our case the constuctor) method is
  only called the first time the component renders. Never more. Meaning
  that, if you re-render that component passing a different value as a
  prop, the component will not react accordingly, because the component
  will keep the state from the first time it was rendered. It's very
  error prone.</p>
  </blockquote>
  <p>Hence why I then implemented useEffect however the console.log in useEffect is still &quot;updateMe&quot; and not the value as returned from the graphql call.</p>
  <p>So where I'm at</p>
  <ul>
  <li>I need the render the functional component after the the grapql call
  and I've manipulated the data, this seems to be the best approach in terms of design patterns also</li>
  </ul>
  <p>or</p>
  <ul>
  <li>I need setState to pass/render the functional component with the new value</li>
  </ul>
  <p>As an aside if I do this</p>
  <pre><code>            &lt;AddTodo  mkey=&quot;ExtraShopDesc&quot; namespace=&quot;ExtraShopDescription&quot; desc={data.shop.metafields.edges[0].node.value} onUpdate={refetch} /&gt; 
  </code></pre>
  <p>It will work but I can't always expect the value to be 0 or 1 as metafields might have already defined</p>