我正在使用webpacker运行React和Rails 5.2。
我在页面顶部有一个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 :(得分:1)
setState
本质上是异步的,短时间内多次setState
次调用会导致批量更新。意味着上次更新获胜。你的第二个setState调用覆盖了第一个。
将setState()视为请求而不是更新组件的立即命令。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不保证立即应用状态更改。
考虑到您没有从之前的状态或道具进行任何计算......您应该将setState调用更改为以下内容:
this.setState({
selected: newValue,
searchPath: `/error_code/search?error_code=${newValue}`
});
如果您需要先前的状态或道具来计算新状态,您还可以将函数用作setState(updater, [callback])
的updater
。
this.setState((prevState, props) => {
return {counter: prevState.counter + props.step};
});
updater函数接收的prevState和props都保证是最新的。 updater的输出与prevState轻微合并。
撇开:请查看Why JSX props should not use arrow functions。内联使用它们是相当有害的。