Component state
The wrong way
Let's first try to simply add a code by updating the array of codes, and then log the updated codes. We expect the new code to appear below the third code.
function CodeListEditor() {
  const codes = [{
    id: 'code_1',
    label: 'unhappy'
  }, {
    id: 'code_2',
    label: 'happy',
  }, {
    id: 'code_3',
    label: 'very happy'
  }]
  const handleClick = () => {
    codes.push({ id: 'code_4', label: 'very unhappy' })
    console.log('codes:', codes)
  }
  return (
    <div>
      <button onClick={handleClick} />
      ...
    </div>
  )
}
As you notice, it does not quite work: the codes seem to have been updated (there are now 4 codes in our array), but the UI stayed the same.
This is a key feature of React: the app will only be re-rendered when a setState method is called somewhere. To use the setState method, we will need to make some adjustments to our CodeListEditor.
The right way
To use the setState method aforementioned, we need to use a different syntax to describe the component: 
import React from 'react'
class CodeListEditor extends React.Component {
  render() {
    const codes = ...
    return (
      <div>
        <button onClick={handleClick} />
        ...
      </div>
    )
  }
}
We've just copied the body from our component function to the body of another function: the render method of a ES6 class which extends React.Component.
For now, nothing has changed: the UI is still not updating when we try to add a code. But this syntax exposes some additional functionalities. Among them is the option to call the setState method to tell the component something has changed and it should be re-rendered. 
import React from 'react'
class CodeListEditor extends React.Component {
  constructor() {
    super()
    //we initialize the state with the 3 codes
    this.state = {
      codes: [{
        id: 'code_1',
        label: 'unhappy'
      }, {
        id: 'code_2',
        label: 'happy',
      }, {
        id: 'code_3',
        label: 'very happy'
      }]
    }
    this.addCode = () => {
      const { codes } = this.state
      const newId = `code_${codes.length+1}`
      //Instead of updating the codes in place, with `codes.push`, we prefer to
      //make a copy of the initial codes and append the new code at the end.
      const newCodes = [...codes, { id: newId, label: 'very unhappy' }]
      //we can now use `setState` to make this new array of codes part of the
      //component state. The `setState` call will trigger a re-rendering of the
      //component.
      this.setState({
        codes: newCodes
      })
    }
  }
  render() {
    //codes should now be extracted from the component state
    const { codes } = this.state
    return (
      <div>
        {/* we use the `addCode` method defined in the constructor */}
        <button onClick={this.addCode}>Add a code</button>
        <div>
        {
          codes.map(({ id, label }) => <CodeEditor key={id} label={label} />)
        }
        </div>
      </div>
    )
  }
}
We intitialize the state of the CodeListEditor component with the 3 already created codes. We then define a addCode function (see arrow functions) which:
- creates an idfor the newly created code;
- creates a copy of the initial codes with a new code at the end (see spread operator) ;
- calls setStateto update the state of the component; thesetStatecall will trigger a re-rendering of the component.
Now, when we click on the "Add a code" button, the UI updates accordingly.
Play with this pen.