Updating state as an array of objects

So I’m stuck trying to set the values for the variable domainRecordsInput, as they’re dynamic. Sometimes there’s one or two rows of data, sometimes there’s six or eight. I need to update specific fields in the right object in an array.

This is as far as I’ve gotten:

enter image description here

  function DomainRecordsTable() {
    const [records, setRecords] = useState(['']);

    const { loading, error, data } = useQuery(GET_DOMAIN_RECORDS, {
      variables: {
        domain: domain,
      },
    });

    useEffect(() => {
      if (data && data.getDomainRecords) {
        setRecords( data.getDomainRecords.host );
      }
    }, [data]);

    const [exeRecords] = useMutation(SET_DOMAIN_RECORDS, {
      variables: {
        domain: domain,
        domainRecordsInput: [{
          hostName: "lol",
          recordType: "lol",
          address: "lol",
          mxPref: "lol",
          ttl: "lol",
        }]
      },
    });

    if (loading) return <LoadingIndicator />;
    if (error) return `Error! ${error.message}`;

    return (
      <>

      <TableComp>
        <Table.Head>
          <Table.Row>
            <Table.Cell>
              <span>type</span>
            </Table.Cell>
            <Table.Cell>
              <span>address</span>
            </Table.Cell>
            <Table.Cell>
              <span>value</span>
            </Table.Cell>
            <Table.Cell>
              <span>priority</span>
            </Table.Cell>
            <Table.Cell>
              <span>ttl</span>
            </Table.Cell>
            <Table.Cell>
              <span>actions</span>
            </Table.Cell>
          </Table.Row>
        </Table.Head>

        <Table.Body>
          {data.getDomainRecords.host.map((e, i) => (
            <Table.Row key={i}>
              <Table.Cell>
                <EasyEdit
                  type="text"
                  value={e.type}
                  onSave={(value) => setRecords((records) => ({ ...records[i], type: value }))}
                />
              </Table.Cell>
              <Table.Cell>
                <EasyEdit
                  type="text"
                  value={e.address}
                  onSave={(value) => setRecords((records) => ({ ...records[i], address: value }))}
                />
              </Table.Cell>
              <Table.Cell truncate={true} align="left">
                <EasyEdit
                  type="text"
                  value={e.name}
                  onSave={(value) => setRecords((records) => ({ ...records[i], name: value }))}
                />
              </Table.Cell>
              {e.type === "MX" ? (
                <Table.Cell align="right">
                  <EasyEdit
                    type="text"
                    value={e.mxPref}
                    onSave={(value) => setRecords((records) => ({ ...records[i], mxPref: value }))}
                  />
                </Table.Cell>
              ) : (
                <Table.Cell></Table.Cell>
              )}
              <Table.Cell>
                <EasyEdit
                  type="text"
                  value={e.ttl}
                  onSave={(value) => setRecords((records) => ({ ...records[i], ttl: value }))}
                />
              </Table.Cell>
              <Table.Cell>
                <button>delete row</button>
              </Table.Cell>
            </Table.Row>
          ))}
        </Table.Body>
      </TableComp>

      <button>add row</button>

      </>
    );
  }

Answer

So this is what I found to work for me:

const [records, setRecords] = useState([""]);

useEffect(() => {
  if (data && data.getDomainRecords) {
    setRecords(data.getDomainRecords.host);
  }
}, [data]);

const updateItem = (prop, event, index) => {
  const old = records[index];
  const updated = { ...old, [prop]: event };
  const clone = [...records];
  clone[index] = updated;
  setRecords(clone);
};

const [exeRecords, { data: datalol }] = useMutation(SET_DOMAIN_RECORDS, {
  variables: {
    domain: domain,
    domainRecordInput: records.flatMap((e) => [
      {
        hostName: e.name,
        recordType: e.type,
        address: e.address,
        mxPref: e.mxPref,
        ttl: e.ttl,
      },
    ]),
  },
});

...

onSave={(e) => updateItem("ttl", e, i)}