Я пытаюсь создать поисковый фильтр в приложении React Rails, который будет фильтровать результаты поиска, когда пользователь печатает / ищет. Я следую за прохождением , которое помогает с этим, но я сталкиваюсь с ошибкой, которая застряла на несколько часов.
Во-первых, вот моя ошибка:
Uncaught TypeError: Cannot read property 'map' of undefined
at SearchFilter.render (SearchFilter.js:28)
Вот мой SearchFilter.js
код компонента:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class SearchFilter extends Component {
constructor(props) {
super(props)
this.state = {
term: '',
autoCompleteResults: [],
itemSelected: {},
showItemSelected: false
}
fetch('/search?q=' + this.state.term)
.then(response => this.setState({ autoCompleteResults: response.librarys }))
}
getAutoCompleteResults(e){
this.setState({
term: e.target.value
}, () => {
fetch('/search?q=' + this.state.term)
.then(response => this.setState({ autoCompleteResults: response.librarys }))
});
}
render(){
let autoCompleteList = this.state.autoCompleteResults.map((response, index) => {
return <div key={index}>
<h2>{response.title}</h2>
<p>{response.desc}</p>
</div>
});
return (
<div>
<input ref={ (input) => { this.searchBar = input } } value={ this.state.term } onChange={ this.getAutoCompleteResults.bind(this) } type='text' placeholder='Search Syntaxes' />
{ autoCompleteList }
</div>
)
}
}
export default SearchFilter
Теперь, насколько я понимаю, новичок , это потому, что мы вызываем map
на autoCompleteResults
, и в настоящее время он настроен на пустой массив и будет до тех пор, пока пользователь фактически не начнет искать / фильтровать результаты (думаю).
Я включу для справки мой основной компонент и код контроллера:
MainPage.js
import React from "react"
import PropTypes from "prop-types"
//data
import { allLibrarys } from '../data/librarys'
//components
import Card from "../Card"
import SearchFilter from '../SearchFilter'
class MainPage extends React.Component {
constructor(props) {
super(props)
this.state = {
librarys: []
}
this.getLibrarys()
}
//Updates state with librarys
getLibrarys = ()=>{
allLibrarys()
.then((librarys)=>{
this.setState({ librarys })
})
.catch((error) => {
this.setState({
error
})
})
}
//Edits cards
handleUpdate = (library) => {
fetch(`http://localhost:3000/libraries/${library.id}`,
{
method: 'PUT',
body: JSON.stringify({library: library}),
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
this.updateLibrary(library)
})
}
updateLibrary(library){
let newLibrarys = this.state.librarys.filter((f) => f.id !== library.id)
newLibrarys.push(library)
this.setState({
librarys: newLibrarys
})
}
render () {
const { activeIndex, librarys } = this.state
const{ handleUpdate } = this
return (
<React.Fragment>
<SearchFilter />
{console.log(librarys)}
<Card librarys={librarys} handleUpdate={handleUpdate}/>
</React.Fragment>
);
}
}
export default MainPage
main_controller.js
class MainController < ApplicationController
before_action :force_json, only: :search
def index; end
def search
@libraries = Library.ransack(title_cont: params[:q]).result(distinct: true).limit(5)
end
private
def force_json
request.format = :json
end
end
Я полагаю, что этот вопрос довольно прост, но, как я уже сказал выше, я часами баловался с ним без всякой удачи. Заранее благодарим за любую помощь в этом.