вкратце: this.setState({ results: body.hits.hits });
не работает
Мне нужно отобразить ответ из индекса ElasticSearch в React.js v16. У меня есть рабочий код для React v ‹ 15.5:
Это я сломал после переписывания с синтаксисом класса ES6:
class App extends Component {
constructor(props) {
super(props)
this.state = { results: [] };
}
handleChange(event) {
const search_query = event.target.value;
client.search({
index: _index,
type: _type,
body: {
query: {
multi_match: {
query: search_query,
fields: ['title^100', 'tags^100', 'abstract^20', 'description^10', 'chapter^5', 'title2^10', 'description2^10'],
fuzziness: 1,
},
},
},
}).then(function(body) {
this.setState({ results: body.hits.hits });
}.bind(this),
function(error) {
console.trace(error.message);
}
);
}
render() {
return (
<div className="container">
<input type="text" onChange={this.handleChange} />
<SearchResults results={this.state.results} />
</div>
);
}
}
Я использую компонент App для установки initialState results в пустой массив внутри конструктора. Затем используйте функцию handleChange, чтобы брать текстовые данные из поля ввода и отправлять их в качестве поисковых запросов в ES. Это работает, я вижу трассировку консоли для body.hits.hits, которая выглядит примерно так:
TRACE: 2017-10-19T09:35:37Z
-> POST http://localhost:9200/myIndex_2017_09_09/article/_search
{
"query": {
"multi_match": {
"query": "query",
"fields": [
"title^100",
"tags^100",
"abstract^20",
"description^10",
"chapter^5",
"title2^10",
"description2^10"
],
"fuzziness": 1
}
}
}
<- 200
{
"took": 19,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 369,
"max_score": 18.169382,
"hits": [
{
"_index": "myIndex_2017_09_09",
"_type": "article",
"_id": "AV5mDaz7Jw6qOfpXAp1g",
"_score": 18.169382,
"_source": {
"title2": "title2",
"series": [
"series1",
"series2",
"series3"
],
"models": [
"models1",
"models2"
],
"description": "description",
"description2": "description2",
"link": "URL",
"title": "title",
"chapter": "chapter",
"tags": [
"tags1",
"tags2",
"tags3"
],
"image": "URL",
"abstract": "abstract"
}
}
]
}
}
Затем я добавляю функцию рендеринга для отображения поля ввода и еще один компонент без сохранения состояния SearchResults для итерации некоторого JSX по ответу. Этот компонент передается this.state.results, который не работает:
const SearchResults = ({results}) => (
<div className="search_results">
<hr />
<table>
<thead>
<tr>
<th>Title</th>
</tr>
</thead>
<tbody>
{results.map((result , i) =>
<ResultRow key={i}
title={result._source.title2} />
)}
</tbody>
</table>
</div>
)
const ResultRow = ({ title }) => (
<tr>
<td>
{title}
</td>
</tr>
)
Состояние SearchResults всегда отображается как пустой массив. Но когда я добавляю некоторые фиктивные данные в конструктор App, это прекрасно отображается:
constructor(props) {
super(props)
this.state = { results: [
{
"_index": "myIndex_2017_09_09",
"_type": "article",
"_id": "AV5mDXcSJw6qOfpXAp0a",
"_score": 5.5604653,
"_source": {
"title2": "title 01",
}
},
{
"_index": "myIndex_2017_09_09",
"_type": "article",
"_id": "AV5mDXcSJw6qOfpXApsa",
"_score": 2.1404631,
"_source": {
"title2": "title 02",
}
}
]}
}
Может ли кто-нибудь заметить ошибку?