Kann ich den Status übergeben und nur 1 Funktion verwenden, anstatt für jede Statuseigenschaft eine Funktion aufzurufen?

Komponentenstatus:

this.state =
{
  context: this.props.context,
  dataProvider: this.props.dataProvider,
  projectInformationDetails: {
    programName: "",
    projectName: "",
    projectStatus: "",
    projectStatusOptions: [],
    appStatus: "",
    appStatusOptions: [],
    governanceStatus: "",
    governanceStatusOptions: []
  },
};

Funktion zum Ändern des Status bei Änderung des Eingangs:

private async setProgramName(e) {
    await this.setState(prevState => ({
        projectInformationDetails: {
            ...prevState.projectInformationDetails,
            programName: e.target.value,
        }
    }));

    this.props.updateProjectItem(this.state.projectInformationDetails);
}

private async setProjectName(e) {
   await this.setState(prevState => ({
      projectInformationDetails: {
         ...prevState.projectInformationDetails,
         projectName: e.target.value,
      }
   }));

   this.props.updateProjectItem(this.state.projectInformationDetails);
}
...

Textkomponente beim Rendern:

<TextField
    label={strings.ProgramNameLabel}
    defaultValue={this.state.projectInformationDetails.programName}
    onChange={this.setProgramName}
/>
<TextField
     label={strings.ProjectNameLabel}
     defaultValue={this.state.projectInformationDetails.projectName}
     onChange={this.setProjectName}
/>
...

Anstatt fast die gleiche Funktion für jeden Zustand zu verwenden, möchte ich nur eine einzige Funktion verwenden:

func (Zustand, Wert)

Vielleicht ist der Code sauberer, wenn ich auf die Eigenschaft von projectInformationDetails zugreifen kann, ohne alles zurück zu klonen.

Beispielsweise:

this.setState( {projectInformationDetails.programName: value});
1
tmach 6 Okt. 2020 im 18:12

2 Antworten

Beste Antwort

Wenn es sich nur um Eingabefelder handelt, können Sie dem Eingabe-Tag einen name Schlüssel hinzufügen. Es würde ungefähr so ​​aussehen wie <input type="text" name="programName" value={programName} /> Der Namenswert würde dann dem Schlüssel entsprechen, den Sie im Status ändern möchten.

Damit sollten Sie in der Lage sein, eine generische Funktion zum Festlegen des Statuswerts zu erstellen.

const onInputChange = (e) => this.setState({
  ...this.state,
  projectInformationDetails: {
    ...this.state.projectInformationDetails,
    [e.target.name]: e.target.value,
  },
});

Verwenden Sie diese Funktion für das Eingabefeld onChange.

Ich habe seit einiger Zeit keine Klassen mit React mehr verwendet, daher müssen wahrscheinlich einige Änderungen vorgenommen werden.

Bearbeiten:

Sie können einen Teil der Antwort von @David Barker einbeziehen, indem Sie den Wert in die Funktion onChange einfügen und Funktionen als erstklassige Bürger verwenden, indem Sie eine andere Funktion zurückgeben.

const onChange = (property) => (e) => this.setState({
  ...this.state,
  projectInformationDetails: {
    ...this.state.projectInformationDetails,
    [property]: e.target.value,
  },
});

...

<TextField
    label={strings.ProjectNameLabel}
    defaultValue={this.state.projectInformationDetails.projectName}
    onChange={onChange('programName')}
/>
1
Paalar 6 Okt. 2020 im 16:05

Sie könnten jeden Ereignishandler aus einer einzigen Methode zusammenstellen. Ich bin mir nicht sicher, ob dadurch Render-Overheads entstehen würden, da React die Ereignishandler nicht verfolgen könnte, wenn dies der Fall wäre, könnten Sie das Ergebnis immer zuweisen Variablen in componentDidMount.

private setComponentState(key) {
    const self = this;
    return (e) => {
        self.setState(prevState => ({
            projectInformationDetails: {
                ...prevState.projectInformationDetails,
                [key]: e.target.value,
            }
        }))
    };
}

Rufen Sie diese Funktion dann jedes Mal auf, wenn Sie sie mit der Taste verwenden möchten.

<TextField
    label={strings.ProgramNameLabel}
    defaultValue={this.state.projectInformationDetails.programName}
    onChange={this.setComponentState('programName')}
/>

<TextField
    label={strings.ProjectNameLabel}
    defaultValue={this.state.projectInformationDetails.projectName}
    onChange={this.setComponentState('projectName')}
/>
1
tmach 6 Okt. 2020 im 16:02