2
votes

I am using Formik with an array, where the items are being passed from a parent and retrieved like this:

updateState (){
    this.state.choices = this.props.choices
    this.state.questionId = this.props.questionId
  }
  render() {
    this.updateState()
    var choices = this.state.choices
    console.log(choices)
    return ( ...

I am originally initializing the values as empty or 0:

  constructor(props){
    super(props);
    this.state = {
      choices : [],
      questionId: 0
    };
  }

While this seems like it should work, I am getting the error that a component is changing an uncontrolled input of type text to be controlled. understand this is due to my use of this.state but I'm unsure how to actually fix this.

What I have done so far, since I am using Formik, is change my export to look like this:

  export default withFormik({
  mapPropsToValues: (props) => ({
    choices: [{
    id: '',
    value: '',
    weight: '',
    impact: ''}]
  }),
})(Choices)

It's unclear if I should be mapping props at all, or if I should be using something more like:

export default withFormik({
  mapPropsToValues: (props) => ({

    id: '',
    value: '',
    weight: '',
    impact: ''
  }),
})(Choices)

All I know is that I am unable to click to push a new object onto the array that I am working with, so the functionality is basically frozen until I can figure out the state of the un/controlled input element.

Any idea where I am going wrong?

1
You should not mutate state like this.state.choices. Use setState instead, set it in the constructor or just use the props directly if you can.Tholle
Changed that, still getting the uncontrolled error. Good spot, thanksDan Fein

1 Answers

3
votes

Fixing the HTML and the {choices[index].id} bits cleared this error.

E.g.:

<div className="col">
                        <label htmlFor={choices[index].id}>{choices[index].id}</label>
                        <Field name={choices[index].id} placeholder={choices[index].value} type="text"/>
                        <ErrorMessage name={choices[index].id} component="div" className="field-error" />
                      </div>