2017-04-08 56 views
1

我在界定函数时遇到了一些麻烦。我试图获得“item”的价值,但当我尝试在函数外部访问它时,我得到了未定义的值。如何使外部的LinkClicked()可以访问“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联系人; - ' – roippi

+0

我在本地运行此程序,一旦我拥有了所有的工作,我会放弃修复该问题。 –

回答

1

定义一个存储结果的全局变量。如果您正在使用反应(您使用的反应级别并未完全显示),则应使用this.setState来设置状态并在其他地方使用它。由于conn.query是异步的,因此不能在conn.query方法之后使用item。如果你想在回调中做它的处理。

我假设你需要渲染函数中的项目。在国家这很容易。

请注意,我将function-定义更改为lambda表达式(() => {})。这是必要的,以便在回调中使用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

你应该使用functionnal setState,就像这个'this.setState((=)=>({item:item})'因为setState是异步的并且有一些缺陷 –

+0

@VincentTaing你的函数也是异步的,并且使用相同的值因为关闭,我没有看到区别 – user3637541

+0

这是很危险的,因为传递一个对象会使状态处于挂起状态,这意味着该状态不会立即发生变化如果尝试从其他地方的setState你会遇到一些冲突,你不知道为什么。如果你通过setState函数而不是一个对象,它会被同步变异。https://facebook.github.io/react/docs/state-and- lifecycle.html#state-updates-may-be-asynchronous –