0

I have a react component with a form for updating database records. Here's the thing: the data is loaded with React-Relay QueryRenderer component as follows:

class Update extends Component {
   //constructor..
   //some stuff
   render() {
    return(
      <QueryRenderer
        environment={environment}
        query={UpdateQuery}
        render={({error, props}) => {
        //validations
          return (
            <Form loading={this.state.loading}>
            //inputs
            </Form>
           )...
      }/>
    )}

The props variable is supposed to store the result from server response if successful. However, I need to call the update with this.state values. I need a way to setState with props values.

I have tried with componentDidMount and using refs both string refs and callback ones to get defaultValue from Inputs. I got undefined values when calling this.refs

For now, it works if I call a function within QueryRenderer render function that sets the state with props if state is empty. E.g

function initValues(props){
  if(!this.state.name)
    this.setState({name: props.result.name})
}

But it results in an anti-pattern (pure render method) that I need to solve.

Edit: For anyone wondering how I solved this. Thanks to charlie's answer I managed to create a UpdateForm component wrapper that receives the props from QueryRenderer, and in order to update my parent's component state I passed my handleChange function as props to my FormUpdate component

Joan Gil
  • 145
  • 3
  • 10

1 Answers1

2

Use componentWillReceiveProps in your Form component

class Form extends React.Component {

    ...

    componentWillReceiveProps(nextProps) {
        if (nextProps.loading) return
        this.setState({
           name: nextProps.name
        })
    }

    ...
}

This will only set the state once as soon as the data is available, since QueryRenderer only calls render once after the data has loaded.

Charlie Martin
  • 8,208
  • 3
  • 35
  • 41
  • Sorry, I forgot to mention that my Form component is just an import from Semantic-Ui-React component. But based in your answer, a workwaround could be creating an actual Form component that wraps the actual form and all the inputs with componentwillReceiveProps? – Joan Gil Nov 29 '17 at 02:12
  • Yes. Just wrap semantic UI's form in your own parent component that holds the state. – Charlie Martin Nov 29 '17 at 03:31
  • In that case, how do I access my form component state from my Update component? My update button (where I update with this.state) is outside the form component. – Joan Gil Nov 29 '17 at 11:55
  • Thank you! I managed to solve my problem thanks to your answer. I edited my answer to comment exactly how I managed to solve this. (For some reason, componentWillReceiveProps was not beign called so I had to use componentDidMount) – Joan Gil Nov 29 '17 at 14:28
  • There was a typo in how I spelled `componentWillReceiveProps` in my answer. I just fixed it. Try again. Should work. It's better to use than `componentDidMount` in this case – Charlie Martin Nov 29 '17 at 18:53