title: React Beginner Question: Textfield Losing Focus On Update
body: <p>I wrote a component that is supposed to list out a bunch of checkboxes with corresponding textfields. When you click on the checkboxes, or type in the fields it's meant to update state. </p>
  
  <p>The textbox is working ok, but when I type in the fields, it updates state ok, but I lose focus whenever I tap the keyboard.</p>
  
  <p>I realized this is probably due to not having keys set, so I added keys to everything but it still is losing focus. At one point I tried adding in stopPropegation on my events because I thought maybe that was causing an issue?? I'm not sure.. still learning...didn't seem to work so I removed that part too.</p>
  
  <p>Still can't seem to figure out what is causing it to lose focus... does anyone have any advice/solves for this issue?</p>
  
  <p>I consolidated my code and cut out the unnecessary bits to make it easier to read. There are three relevant JS files.. please see below:</p>
  
  <p>I'm still a beginner/learning so if you have useful advice related to any part of this code, feel free to offer. Thanks!</p>
  
  <p>App.js</p>
  
  <pre><code>import React, { Component } from 'react';
  import Form from './Form'
  
  class App extends Component {
  constructor() {
    super();
    this.state = {
        mediaDeliverables: [
          {label: 'badf', checked: false, quantity:''},
          {label: 'adfadf', checked: false, quantity:''},
          {label: 'adadf', checked: false, quantity:''},
          {label: 'addadf', checked: false, quantity:''},
          {label: 'adfdes', checked: false, quantity:''},
          {label: 'hghdgs', checked: false, quantity:''},
          {label: 'srtnf', checked: false, quantity:''},
          {label: 'xfthd', checked: false, quantity:''},
          {label: 'sbnhrr', checked: false, quantity:''},
          {label: 'sfghhh', checked: false, quantity:''},
          {label: 'sssddrr', checked: false, quantity:''}
        ]
    }
  }
  
  setMediaDeliverable = (value, index) =&gt; {
    let currentState = this.getStateCopy();
    currentState.mediaDeliverables[index] = value;
    this.setState(currentState);
  } 
  
  getStateCopy = () =&gt; Object.assign({}, this.state);
  
  render() {
    return (
      &lt;div className="App"&gt;
            &lt;Form 
              key="mainForm"
              mediaDeliverablesOptions={this.state.mediaDeliverables}
              setMediaDeliverable={this.setMediaDeliverable}
            /&gt;  
      &lt;/div&gt;
    );
    }
  }
  export default App;
  </code></pre>
  
  <p>Form.js</p>
  
  <pre><code>import React from 'react';
  import { makeStyles, useTheme } from '@material-ui/core/styles';
  import FormControl from '@material-ui/core/FormControl';
  import FormLabel from '@material-ui/core/FormLabel';
  import FormGroup from '@material-ui/core/FormGroup';
  import FormControlLabel from '@material-ui/core/FormControlLabel';
  import Checkbox from '@material-ui/core/Checkbox';
  import MediaDeliverablesCheckBox from './MediaDeliverablesCheckBox';
  
  
  const useStyles = makeStyles(theme =&gt; ({
    container: {
      display: 'inline-block',
      flexWrap: 'wrap',
    },
    root: {
      display: 'inline-block',
      flexWrap: 'wrap',
      maxWidth: 600,
      textAlign: 'left',
    },
    extendedIcon: {
      marginRight: theme.spacing(1),
    },
    formControl: {
      margin: theme.spacing(1),
      minWidth: 120,
      maxWidth: 300,
    },
    textField: {
      marginLeft: theme.spacing(1),
      marginRight: theme.spacing(1),
      width: 370,
    },
    dense: {
      marginTop: 19,
    },
    chips: {
      display: 'flex',
      flexWrap: 'wrap',
    },
    chip: {
      margin: 2,
    },
    noLabel: {
      marginTop: theme.spacing(3),
    },
  }));
  
  const ITEM_HEIGHT = 48;
  const ITEM_PADDING_TOP = 8;
  const MenuProps = {
    PaperProps: {
      style: {
        maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
        width: 250,
      },
    },
  };
  
  function getStyles(name, accountName, theme) {
    // console.log('&gt;&gt; [form.js] (getStyles) ',accountName)
    return {
      fontWeight:
        accountName.indexOf(name) === -1
          ? theme.typography.fontWeightRegular
          : theme.typography.fontWeightMedium,
    };
  }
  
  
  
  export default function Form(props) {
  
    const mediaDeliverablesOptions = props.mediaDeliverablesOptions;
    const classes = useStyles();
    const theme = useTheme();
  
    const CheckboxGroup = ({ values, label, onChange }) =&gt; (
    &lt;FormControl component="fieldset"&gt;
      &lt;FormLabel component="legend"&gt;{label}&lt;/FormLabel&gt;
      &lt;FormGroup&gt;
        {values.map((value, index) =&gt; (
          &lt;FormControlLabel
            key={index}
            control={
              &lt;Checkbox
                checked={value.checked}
                onChange={onChange(index)}
              /&gt;
            }
            label={value.label}
          /&gt;
        ))}
      &lt;/FormGroup&gt;
    &lt;/FormControl&gt;
  );
  
    const MediaDeliverableCheckBoxList = ({values, label}) =&gt; (
      &lt;FormControl component="fieldset"&gt;
      &lt;FormLabel component="legend"&gt;{label}&lt;/FormLabel&gt;
      &lt;FormGroup&gt;
      {values.map((value, index) =&gt; (
          &lt;MediaDeliverablesCheckBox
          key={index}
          mediaDeliverablesOptions={value}
          onMediaDeliverableChange={onMediaDeliverableChange(index)}
        /&gt;
        ))}
      &lt;/FormGroup&gt;
    &lt;/FormControl&gt;
      );
  
  
  
    const onCheckBoxChange = index =&gt; ({ target: { checked } }) =&gt; {
      const newValues = [...values];
      const value = values[index];
      newValues[index] = { ...value, checked };
      props.setDesignOrDigital(newValues);
    };
  
    const onMediaDeliverableChange = index =&gt; (deliverableData, e) =&gt; {
      props.setMediaDeliverable(deliverableData, index);
    }
  
    return (
      &lt;div className={classes.root}&gt;
        &lt;MediaDeliverableCheckBoxList
          label="Please Choose Deliverables:"
          values={mediaDeliverablesOptions}
          key="media-deliverable-checkbox-list"
        /&gt;
      &lt;/div&gt;
    );
  }
  </code></pre>
  
  <p>MediaDeliverablesCheckbox.js</p>
  
  <pre><code>import React from 'react';
  import Checkbox from '@material-ui/core/Checkbox';
  import { makeStyles, useTheme } from '@material-ui/core/styles';
  import FormControl from '@material-ui/core/FormControl';
  import FormLabel from '@material-ui/core/FormLabel';
  import FormGroup from '@material-ui/core/FormGroup';
  import FormControlLabel from '@material-ui/core/FormControlLabel';
  import TextField from '@material-ui/core/TextField';
  
  export default function MediaDeliverablesCheckBox(props) {
  
    let deliverableData = Object.assign({}, props.mediaDeliverablesOptions);
  
    const onCheckBoxChange = (e) =&gt; {
       deliverableData.checked = e.target.checked;
       props.onMediaDeliverableChange(deliverableData, e);
    }
  
    const onQuantityChange = (e) =&gt; {
       deliverableData.quantity = e.target.value;
       props.onMediaDeliverableChange(deliverableData, e);
    }
  
    const CheckboxGroup = ({ value, label }) =&gt; (
  
    &lt;FormControl component="fieldset"&gt;
      &lt;FormGroup&gt;
          &lt;FormControlLabel
            control={
              &lt;Checkbox
                key={props.index}
                checked={value.checked}
                onChange={onCheckBoxChange}
              /&gt;
            }
            label={label}
          /&gt;
      &lt;/FormGroup&gt;
    &lt;/FormControl&gt;
    );
  
  return(
      &lt;div className="MediaDeliverablesCheckBox"&gt;
        &lt;CheckboxGroup
              key={props.index}
              label={props.mediaDeliverablesOptions.label}
              value={props.mediaDeliverablesOptions}
            /&gt;
        &lt;TextField
          key={'tf'+props.index}
          id={'quantity-'+props.index}
          label="Quantity"
          placeholder="How many do you need?"
          multiline
          variant="outlined"
          value={props.mediaDeliverablesOptions.quantity}
          onChange={onQuantityChange}
          fullWidth
        /&gt;
      &lt;/div&gt;
    );
  }
  </code></pre>
  
  <p>Updated Form.js based on recommended edits by Ryan C.</p>
  
  <pre><code>import React from 'react';
  import { makeStyles, useTheme } from '@material-ui/core/styles';
  import FormControl from '@material-ui/core/FormControl';
  import FormLabel from '@material-ui/core/FormLabel';
  import FormGroup from '@material-ui/core/FormGroup';
  import FormControlLabel from '@material-ui/core/FormControlLabel';
  import Checkbox from '@material-ui/core/Checkbox';
  import MediaDeliverablesCheckBox from './MediaDeliverablesCheckBox';
  
  
  const useStyles = makeStyles(theme =&gt; ({
    container: {
      display: 'inline-block',
      flexWrap: 'wrap',
    },
    root: {
      display: 'inline-block',
      flexWrap: 'wrap',
      maxWidth: 600,
      textAlign: 'left',
    },
    extendedIcon: {
      marginRight: theme.spacing(1),
    },
    formControl: {
      margin: theme.spacing(1),
      minWidth: 120,
      maxWidth: 300,
    },
    textField: {
      marginLeft: theme.spacing(1),
      marginRight: theme.spacing(1),
      width: 370,
    },
    dense: {
      marginTop: 19,
    },
    chips: {
      display: 'flex',
      flexWrap: 'wrap',
    },
    chip: {
      margin: 2,
    },
    noLabel: {
      marginTop: theme.spacing(3),
    },
  }));
  
  const ITEM_HEIGHT = 48;
  const ITEM_PADDING_TOP = 8;
  const MenuProps = {
    PaperProps: {
      style: {
        maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
        width: 250,
      },
    },
  };
  
  function getStyles(name, accountName, theme) {
    return {
      fontWeight:
        accountName.indexOf(name) === -1
          ? theme.typography.fontWeightRegular
          : theme.typography.fontWeightMedium,
    };
  }
  
  
  // Failed to compile
  // ./src/Form.js
  //   Line 86:  Parsing error: Unexpected token, expected ","
  
  //   84 | 
  //   85 | const MediaDeliverableCheckBoxList = ({values, label, onMediaDeliverableChange}) =&gt; (
  // &gt; 86 |     {values.map((value, index) =&gt; (
  //      |            ^
  //   87 |         &lt;MediaDeliverablesCheckBox
  //   88 |         key={index}
  //   89 |         index={index}
  // This error occurred during the build time and cannot be dismissed.
  
  const MediaDeliverableCheckBoxList = ({values, label, onMediaDeliverableChange}) =&gt; (
      {values.map((value, index) =&gt; (
          &lt;MediaDeliverablesCheckBox
          key={index}
          index={index}
          mediaDeliverablesOptions={value}
          onMediaDeliverableChange={onMediaDeliverableChange(index)}
        /&gt;
        ))}
  );
  
  export default function Form(props) {
  
    const mediaDeliverablesOptions = props.mediaDeliverablesOptions;
    const classes = useStyles();
    const theme = useTheme();
  
    const CheckboxGroup = ({ values, label, onChange }) =&gt; (
    &lt;FormControl component="fieldset"&gt;
      &lt;FormLabel component="legend"&gt;{label}&lt;/FormLabel&gt;
      &lt;FormGroup&gt;
        {values.map((value, index) =&gt; (
          &lt;FormControlLabel
            key={index}
            control={
              &lt;Checkbox
                checked={value.checked}
                onChange={onChange(index)}
              /&gt;
            }
            label={value.label}
          /&gt;
        ))}
      &lt;/FormGroup&gt;
    &lt;/FormControl&gt;
  );
  
  
    const onCheckBoxChange = index =&gt; ({ target: { checked } }) =&gt; {
      const newValues = [...values];
      const value = values[index];
      newValues[index] = { ...value, checked };
      props.setDesignOrDigital(newValues);
    };
  
    const onMediaDeliverableChange = index =&gt; (deliverableData, e) =&gt; {
      props.setMediaDeliverable(deliverableData, index);
    }
  
    return (
      &lt;div className={classes.root}&gt;
        &lt;MediaDeliverableCheckBoxList
          onMediaDeliverableChange={onMediaDeliverableChange}
        /&gt;
      &lt;/div&gt;
    );
  }
  </code></pre>