2016-11-02 278 views
0

私は入力(jobId)とスパン(jobDescription)からなる単純なコンポーネントを持っています。ユーザーがjobIdを入力すると、コンポーネントはajaxを呼び出して説明を入力します。簡単に聞こえます。しかし、ここで私の問題は、私がそれを書いた方法です、コンポーネントは、それぞれのkeypressでjobDescriptionを検索するための無駄な呼び出しの束を作ります。すべてのキーストロークではなく、入力変更イベントをトラップする方法はありますか?

私はlookupをonChangeの代わりにonBlurに変更しようとしましたが、 "initial load"(jobIdが親から渡されたときの最初のレンダリング)が欠けています。フォームが最初に開かれたときにjobDescriptionが空白になります。だからここ

は、私は必要なものである:

  1. JOBIDで、ユーザーのタイプは、対応するjobDescriptionにを検索する場合。しかし必ずしもすべてのキーストロークではない。
  2. 親がjobIdを渡すと、対応するjobDescriptionも参照する必要があります。ここで

それが今あるようなコンポーネントです:

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); 
        }); 
     }); 
    }; 
} 

そしてここでは、親コンポーネントのサンプルです:

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> 
     ); 
    } 
} 

だから、私がしようとしているかを理解誰と仮定あなたはこのコンポーネントをReactにどのように記述しますか?

答えて

0

リクエストを行う前に特定の時間待つ必要があります。これは、主にリクエストを遅延させ、ユーザの入力を待つことです。あなたはまた、与えられた時間のための関数呼び出しを遅らせますLodash's Debounce.これをチェックする必要があります。この

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. 

}; 

のようなものにあなたのonChangeハンドラを変更します。

希望すると便利です。

関連する問題