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。内联使用它们是非常不利的。