2017-08-03 40 views
0

使用webpacker運行React和Rails 5.2。將反應組件的屬性傳遞給rails後端

我在頁面頂部有一個ElasticSearch搜索欄,我無法將正確的請求發送到後端,並且允許rails後端處理搜索請求。

我們現在沒有準備好將此作爲SPA的權利,但我似乎無法得到填充的參數。

import React, {Component} from 'react'; 
import ReactDOM from 'react-dom'; 

import {asyncContainer, Typeahead} from 'react-bootstrap-typeahead'; 

const AsyncTypeahead = asyncContainer(Typeahead); 

class SearchBar extends Component { 


    constructor(props) { 
     super(props) 
     this.state = { 
      options: ['Please Type Your Query'], 
      searchPath: '/error_code/search', 
      selected: [""], 
     } 

     this.handleSubmit = this.handleSubmit.bind(this); 
     this.handleChange = this.handleChange.bind(this); 
    } 

    searchErrorCodes(term) { 
     fetch(`/error_code/auto?query=${term}`) 
      .then(resp => resp.json()) 
      .then(json => this.setState({options: json})) 
    } 


    handleChange(error_code_name) { 
     let newValue = error_code_name 

     this.setState({ 
      selected: newValue 
     }); 

     this.setState({ 
      searchPath: `/error_code/search?error_code=${this.state.selected}`, 
     }); 


     console.log(`This is the new searchPath is ${this.state.searchPath}`); 
    } 

    handleSubmit(e) { 
     alert(`submitted: ${this.state.selected}`); 
     // event.preventDefault(); 
    } 


    render() { 

     return (
      <div> 
       <form ref="form" 
         action={this.state.searchPath} 
         acceptCharset="UTF-8" 
         method="get" 
         onSubmit={e => this.handleSubmit(e)} 
       > 
        <AsyncTypeahead 
         onSearch={term => this.searchErrorCodes(term)} 
         options={this.state.options} 
         className="search" 
         onClick={e => this.handleSubmit(e)} 
         selected={this.state.selected} 
         onChange={e => this.handleChange(e)} 
        /> 
        <button 
         action={this.state.searchPath} 
         acceptCharset="UTF-8" 
         method="get" 
         type="submit" 
         className="btn btn-sm btn-search"> 
         <i className="fa fa-search"></i> 
        </button> 
       </form> 
      </div> 
     ) 
    } 
} 

ReactDOM.render(<SearchBar/>, document.querySelector('.search-bar')); 

一切都呈現正確,但輸入未正確發送到控制器。

+0

當您觸發'this.setState({searchPath:'/ error_code/search?error_code = $ {this.state.selected}', });'時,它會發送'this的舊值。 state.selected',而不是你剛剛設置的那個? – Denialos

+0

據我可以告訴它得到更新,但當你點擊提交時,表單按鈕或某些東西不會傳遞該更新。並且它沒有發送數據到後端 –

+0

我會在你回答這個問題後添加到我的答案中。你如何從'onChange = {e => this.handleChange(e)}'獲得'error_code_name'?在這種情況下,內聯es6箭頭功能是無關緊要的,並且還會導致性能問題並打破淺層比較。 –

回答

1

setState本質上是異步的,在短時間內調用多個setState會導致批量更新。最後一次更新意味着勝利。你的第二個setState調用覆蓋第一個。

將setState()視爲請求而不是立即更新組件的命令。爲了獲得更好的感知性能,React可能會延遲它,然後一次更新幾個組件。 React不保證立即應用狀態更改。

考慮你是不是做從以前的狀態或任何道具......計算你應該你的setState電話更改爲以下:

this.setState({ 
    selected: newValue, 
    searchPath: `/error_code/search?error_code=${newValue}` 
}); 

你也可以使用一個函數作爲updatersetState(updater, [callback]) 如果您需要先行狀態或道具來計算新狀態。

this.setState((prevState, props) => { 
    return {counter: prevState.counter + props.step}; 
}); 

兩個prevState並且由更新器功能接收道具保證是向上的更新。更新程序的輸出與prevState很淺的合併。

順便:請看看Why JSX props should not use arrow functions。內聯使用它們是非常不利的。

相關問題