Я немного новичок в React и Firestore и уже пытаюсь выяснить, что происходит в течение пары часов. Пытаюсь заставить мою функцию фильтра работать с данными, которые я получаю из Firestore в APP.js. Я передаю данные {tasks, searchTerm} компоненту DASHBOARD. Фильтр работал раньше при использовании состояний и реквизитов, но после замены жестко закодированных данных в состоянии данными из хранилища он больше не работает, и я получаю следующую ошибку при фильтрации массива в компоненте DASHBOARD:
Невозможно прочитать свойство 'toLowerCase' из неопределенного
Я пытался отправить данные без какой-либо фильтрации непосредственно в TASKS.js, и это работает правильно (все задачи показаны). Но как только я передаю newArray, он больше не работает.
Кроме того, при регистрации файла task.title в функции tasks.filter в компоненте DASHBOARD отображаются все данные (с небольшой задержкой, поскольку данные поступают из Firestore)
APP.JS -
import React, { Component } from 'react';
import './App.css';
import Dashboard from './Components/Dashboard/Dashboard'
import AddTask from './Components/Tasks/Task/AddTask'
import Navbar from './Components/Navbar/Navbar'
import Searchbar from './Components/Searchbar/Searchbar'
import firebase from './Firebase';
class App extends Component {
constructor(props) {
super(props)
this.ref = firebase.firestore().collection('tasks')
this.state = {
tasks: [],
searchTerm: ""
}
this.handleLikeButton = this.handleLikeButton.bind(this)
this.handleRemoveButton = this.handleRemoveButton.bind(this)
this.addTask = this.addTask.bind(this)
this.handleFilter = this.handleFilter.bind(this)
}
componentWillMount() {
const db = firebase.firestore()
const allTasks = []
db.collection('tasks').onSnapshot(collection => {
const tasks = collection .docs.map(doc => doc.data())
this.setState({ tasks: tasks, searchTerm: "" })
})
}
handleLikeButton = (task) => (e) => {
const tasks = [...this.state.tasks]
const index = tasks.indexOf(task)
tasks[index].likes++
this.setState({
tasks: tasks
})
}
addTask = (taskName) => (e) => {
this.ref.add({
id: Math.floor(Math.random() * 100000000000000),
title: taskName,
likes: 0
})
}
handleRemoveButton = (removingTask) => (e) => {
const tasks = [...this.state.tasks]
const newTasks = tasks.filter(task => removingTask.id !== task.id)
this.setState({
tasks: newTasks
})
}
handleFilter = (searchTerm) => {
this.setState({
searchTerm: searchTerm
})
}
render() {
return (
<div className="App">
<Navbar />
<Searchbar handleFilter={this.handleFilter} />
<AddTask addTask={this.addTask} />
<Dashboard tasks={this.state.tasks} searchTerm={this.state.searchTerm} handleLikeButton={this.handleLikeButton} handleRemoveButton={this.handleRemoveButton}/>
</div>
);
}
}
export default App;
DASHBOARD.JS -
import React, { Component } from 'react'
import Tasks from '../Tasks/Tasks'
class Dashboard extends Component {
constructor(props) {
super(props)
this.filterTasks = this.filterTasks.bind(this)
}
filterTasks = () => {
const tasks = [...this.props.tasks]
const newArray = tasks.filter(task =>
task.title.toLowerCase().indexOf(this.props.searchTerm.toLowerCase()) > -1)
return (
<Tasks tasks={newArray} handleLikeButton={this.props.handleLikeButton} handleRemoveButton={this.props.handleRemoveButton} />
)
}
render() {
return (
<div>
<h2>Dashboard</h2>
{this.filterTasks()}
</div>
)
}
}
export default Dashboard
ADDTASK.JS
import React, { Component } from 'react'
class AddTask extends Component {
constructor(props) {
super(props)
this.state = {
addNewTaskFieldEmpty: true,
taskName: ""
}
this.onChangeHandler = this.onChangeHandler.bind(this)
this.disableButton = this.disableButton.bind(this)
}
onChangeHandler(e) {
this.setState({
taskName: e.target.value,
})
this.disableButton(e.target.value)
}
disableButton(taskName) {
if(taskName.length == 0) {
this.setState({addNewTaskFieldEmpty: true})
} else {
this.setState({addNewTaskFieldEmpty: false})
}
}
render() {
return (
<div>
<div className="mdc-text-field half-size">
<input className="mdc-text-field__input " onChange={this.onChangeHandler} />
<div className="mdc-line-ripple"></div>
<label className="mdc-floating-label">Task Name</label>
</div>
<a className={"btn-floating btn-large waves-effect waves-light red " + (this.state.addNewTaskFieldEmpty ? 'disabled' : '')} onClick={this.props.addTask(this.state.taskName)}><i className="material-icons">add</i></a>
</div>
)
}
}
export default AddTask