2016-11-02 1 views
0

Ich habe eine einfache Komponente, bestehend aus einer Eingabe (JobId) und einem span (jobDescription). Wenn der Benutzer eine Job-ID eingibt, führt die Komponente einen Ajax-Aufruf aus, um die Beschreibung auszufüllen. Klingt einfach. Aber hier ist mein Problem, so wie ich es geschrieben habe, macht die Komponente einen Haufen verschwenderischer Anrufe, um die JobDescription mit jedem Tastendruck nachzuschlagen.Wie fangen Sie Eingabeänderungsereignisse ab, aber nicht jeden Tastendruck?

Ich habe versucht, das Nachschlagen zu OnBlur statt onChange zu ändern, aber dann vermisse ich die "initial load" (das anfängliche Rendern, wenn die JobId vom übergeordneten übergeben wird). Daher ist jobDescription leer, wenn das Formular zum ersten Mal geöffnet wird.

So, hier ist das, was ich brauche:

  1. Wenn der Benutzer in einem jobId, die entsprechende Jobbeschreibung Nachschlag. Aber nicht unbedingt bei jedem Schlüsselstrich.
  2. Wenn das übergeordnete Element eine jobId übergibt, sollte es auch die entsprechende jobDescription suchen. Hier

ist die Komponente, wie es jetzt ist:

import React from "react"; 

type Props = { 
    jobId:string, 
    onChange:(jobId: string)=>void 
} 

type State = { 
    description:string 
} 

export default class JobComponent extends React.Component { 

    props: Props; 
    state: State; 

    constructor(props: Props) { 
     super(props); 
     this.state = { 
      description: "" 
     } 
    } 

    componentWillReceiveProps(nextProps: Props) { 
     if (nextProps.jobId != this.props.jobId) { 
      this.loadDescription(nextProps.jobId) 
       .then((description)=> { 
        this.setState({description}); 
       }); 
     } 
    } 

    onChangeInternal = (event)=> { 
     const jobId = event.target.value; 
     this.props.onChange(jobId); 
     this.loadDescription(jobId) 
      .then((description)=> { 
       this.setState({description}); 
      }); 
    }; 

    render() { 
     return <div> 
      <input className="job-id" value={this.props.jobId} onChange={this.onChangeInternal}/> 
      <span className="job-description">{this.state.description}</span> 
     </div>; 
    } 

    loadDescription = (jobId): Promise<string> => { 
     return new Promise((resolve) => { 
      if (!jobId) resolve(""); 
      else 
       fetch('/components/job-picker/jobService.jsp?jobId=' + jobId) 
        .then((response) => { 
         return response.json(); 
        }) 
        .then((job) => { 
         resolve(job.description); 
        }); 
     }); 
    }; 
} 

Und hier ist ein Beispiel für die übergeordnete Komponente:

import React from "react"; 
import JobComponent from "./JobComponent"; 

export default class FormTest extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      name: "Dave", 
      jobId: "360107", 
      age: 50 
     } 
    } 
    render() { 
     const onNameChange = (event)=> { 
      this.setState({name: event.target.value}); 
     }; 
     const onAgeChange = (event)=> { 
      this.setState({age: event.target.value}); 
     }; 
     const onJobIdChange = (jobId)=> { 
      this.setState({jobId}); 
     }; 
     return (
      <div> 
       Name<input value={this.state.name} onChange={onNameChange}/><br/> 
       JobId<JobComponent jobId={this.state.jobId} onChange={onJobIdChange}/><br/> 
       Age<input value={this.state.age} onChange={onAgeChange}/><br/> 
      </div> 
     ); 
    } 
} 

Also, vorausgesetzt, die verstehen, was ich versuche zu Wie würdest du diese Komponente in React schreiben?

Antwort

0

Sie sollten eine bestimmte Zeit warten, bevor Sie eine Anfrage stellen. Dies verzögert in erster Linie die Anfrage und wartet auf Benutzereingaben. Ändern Sie Ihre onChange Handler so etwas wie dieses

onChangeInternal = (event)=> { 
    const jobId = event.target.value; 
    this.props.onChange(jobId); 
    clearTimeout(this.timeoutId); // resets the timeout on new input 
    this.timeoutId = setTimeout(() => { 
     this.loadDescription(jobId) 
     .then((description)=> { 
      this.setState({description}); 
     }); 
    }, 500); //delays request by 500ms. 

}; 

Sie auch Lodash's Debounce. überprüfen sollten, dies wird der Funktionsaufruf für eine bestimmte Zeit verzögern.

Hoffe, das hilft!

Verwandte Themen