2017-04-08 8 views
1

スコープ機能に問題があります。私は "item"の値を取得しようとしていますが、関数の外部でアクセスしようとすると定義されません。どうすれば "アイテム"を外部からアクセスできるようにすることができますか?レンダリングでアイテムを使用できるようにする必要があります。JS/Reactでネストされた関数に外部からアクセスするには?

onLinkClicked() { 

    var parent = this.state.username 
     //console.log(this.state.username) 
    var conn = new jsforce.Connection({ 
     serverUrl: 'https://cs63.salesforce.com', 
     accessToken: sessionStorage.getItem('token') 
    }) 
    conn.query("SELECT Id, Name, Phone FROM Contact WHERE LastName='" + parent + "'", 
     function(err, result) { 
      if (err) { 
       return console.error(err); 
      } 

      var a = result 
       a.records.forEach(function(item) { 
       result = (item.Name + ' ' + item.Phone); 

       console.log(item) // I'm trying to get the value of item, which outputs correctly here 

      }); 

     } 
    ) 

    console.log(item) //Here I get undefined due to being out of scope, how can I access item?. 

    } 

render() { 

return (
    <div className='menubox' id='menubox'> 
    <div className='searchbar-container'> 
    <form onSubmit={e => e.preventDefault()}> 
     <input 
     type='text' 
     size='25' 
     placeholder='Contact Last Name' 
     onChange={this.handleChange.bind(this)} 
     value={this.state.username} /> 
     <button 
     type='submit' 
     onClick={this.onLinkClicked.bind(this)}> 
     Search 
     </button> 
    </form> 
    </div> 
    <div dangerouslySetInnerHTML={ { __html: item } }> 
    </div> 
    </div> 

) 
} 
+0

インデント、スペース、セミコロンを修正してください。あなたのコードは読めないものです。 – user3637541

+0

私は誰も誰の名前も 'Robert 'であることを願っています。 DROP TABLE Con​​tact; - ' – roippi

+0

私はこれをローカルで実行しています。すべての作業が完了したら、それを修正するためにエスケープします。 –

答えて

1

結果を格納するグローバル変数を定義します。反応を使用している場合(使用している反応クラスは完全には表示されていません)、this.setStateを使用して状態を設定し、別の場所で使用してください。 conn.queryは非同期であるため、conn.queryメソッドの後にitemを使用することはできません。あなたがコールバックでそれを行う処理をしたい場合。

レンダリング機能でitemが必要であると仮定しました。状態でこれは容易に可能です。

functionの定義をラムダ式(() => {})に変更しました。これは、コールバック内でthisを使用するために必要です。

...() { 
    // ... 
    conn.query("SELECT Id, Name, Phone FROM Contact WHERE LastName='" + parent + "'", 
      (err, result) => { 
      if (err) { 
       return console.error(err); 
      } 

      var a = result; 
      a.records.forEach((item) => { 
       result = (item.Name + ' ' + item.Phone); 
       this.setState({item : item}); 
      }); 

      }; 
     ); 

    // You will never be able to get item here, because you are using an 
    // asynchronous function. If you want to use item further in this 
    // function you have to use it within the callback of conn.query. 
    console.log(item); 
}; 

render() { 
    // Nevertheless you can use this.state.item here. I assume this is 
    // what you want. 
    return (// ... 
); 
} 
+0

setStateは非同期であり、いくつかの落とし穴があるので、this.setState(()=>(item:item))のようにfunctionnal setStateを使うべきです –

+0

@VincentTaing関数は非同期でも同じ値を使用します – user3637541

+0

オブジェクトを渡すと状態が保留状態になるため、状態が即座に変更されることはないため、危険です。setStateを他の場所から取得しようとすると、あなたは何らかの矛盾が発生し、その理由を知らないでしょう。オブジェクトではなく関数をsetStateに渡すと、それは同期的に変更されます。https://facebook.github.io/react/docs/state-and- lifecycle.html#state-updates-may-be-asynchronous –

関連する問題