React

HTML

<div id="app"></div>

CSS

body {
  background: #333333;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #ffffee;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
  border: 1px solid black;
  padding:5px;
  background-color:#ffffdd;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

const ModuleElement = (props) => {
  const blockElement = props.config;

  const key = props.index;

  const changeValue = (e) => {
    e.preventDefault();
    console.log(
      `updating the attribute ${e.target.name} with the value "${e.target.value}" of the object `,
      blockElement
    );
    blockElement[e.target.name] = e.target.value;
    props.updateBlock(key, blockElement);
  };

  return (
    <React.Fragment>
      <div className="form-group row" key={`block_${key}`}>
        <input
          key={`block_input_${key}`}
          type="text"
          className="form-control"
          id={`fieldname_${key}`}
          name="fieldName"
          onChange={changeValue}
          placeholder="Field Name"
          defaultValue={blockElement.fieldName}
        />
      </div>
    </React.Fragment>
  );
};
 
 
const ModuleBuilder = () => {
 
  const emptyBlock = {
    fieldName: "",
    required: true,
  };

  const [blocks, setBlocks] = React.useState([emptyBlock]);

  const updateBlock = (key, data) => {
    console.log(`i was asked to update element #${key}`);
    console.log("this is data", data);

    let copyOfBlocks = blocks;

    //copyOfBlocks[key] = data;
    // WHY DOES COMMENTING THIS OUT STILL MAKE THE UPDATE WORK??

    setBlocks([...copyOfBlocks]);
    console.log("this is blocks", blocks);
  };

  const add1Block = () => {
    setBlocks([...blocks, emptyBlock]);
  };

  const renderBlockFormElements = () => {
    return blocks.map((value, index) => {
      return (
        <li key={index}>
          <b>Subcomponent with Index #{index}</b>
          <ModuleElement
            index={index}
            config={value}
            updateBlock={updateBlock}
          />
        </li>
      );
    });
  };

  return (
    <div>
      <h1>
        Click twice on "add another field" then enter something into the second
        field..{" "}
      </h1>
      <h2>Why is 1st field affected??</h2>
      <form>
        <ul...