What type of event should I set this method to?

What type of event should I set the setEndpointState method of this component to. I tried setting it to React.FormEvent<HTMLFormElement> but then I get a type error in the setState function saying that I am missing props name, hostname and description. Is the type of the event wrong or is there a way to write the setState function differently?

import * as React from "react";
import EditBasicInfoForm from "./EditBasicInfoForm";
import { Endpoint } from "../../Endpoints/model";

interface EditBasicInfoProps {
  editBasicInfo: (endpoint: Endpoint) => void;
  ocid: string;
}

interface EditBasicInfoState {
  name: string;
  hostname: string;
  description: string;
}

export class EditBasicInfo extends React.Component<EditBasicInfoProps & EditBasicInfoState, EditBasicInfoState> {
  constructor(props: any) {
    super(props);

    this.state = {
      name: "",
      hostname: "",
      description: ""
    };

    this.setEndpointState = this.setEndpointState.bind(this);
    this.editBasicInfo = this.editBasicInfo.bind(this);
  }

  public setEndpointState(e: React.FormEvent<HTMLFormElement>): void {
    const target = e.currentTarget;
    const value = target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }

  public editBasicInfo(): void {
    const endpoint: any = {
      name: this.state.name,
      hostname: this.state.hostname,
      description: this.state.description,
      ocid: this.props.ocid,
    };

    this.props.editBasicInfo(endpoint);
  }

  public render(): JSX.Element {
    return (
      <>
        <EditBasicInfoForm
          name={this.state.name}
          hostname={this.state.hostname}
          description={this.state.description}
          handleChange={this.setEndpointState}
          handleSubmit={this.editBasicInfo}
        />
      </>
    );
  }
}

export default EditBasicInfo;

2 answers

  • answered 2018-03-22 16:59 Lior Zisman

    Notice - your state implements the interface EditBasicInfoState, hence every time you setState, it expects a full state that implements that interface to be provided.

    You are currently providing it with an object that uses the name as a dynamic key (which probably doesn't exist even on your state), and you are missing the rest of the fields.

    See if setting the state with this object {name: '', hostname: '', description: ''} removes the error, just to be sure this is indeed the problem.

    If this indeed solves your problem, I suggest going back to the meaning of interfaces in Typescript, and reading about Partial.

  • answered 2018-03-22 16:59 vanegeek

    This is what worked for me. Thanks for all the help!

    public setEndpointState(e: React.SyntheticEvent<HTMLInputElement>): void {
        const target = e.currentTarget;
        const name = target.name;
        const value = target.value;
    
        this.setState({
          ...this.state,
          [name]: value
        });
      }