Cannot read property 'toLowerCase' of undefined - REACT - FIRESTORE

99封情书 提交于 2020-03-05 03:40:30

问题


I'm a bit new to React and Firestore and already trying to figure out what is happening for a couple of hours. I Try to make my filter function working with data which I receive from Firestore in APP.js. I pass the data {tasks, searchTerm} to DASHBOARD component. The filter worked before when using state and props, but after replacing the hard-coded data in state with firestore data, it doesn't work anymore and I get the following error when filtering the array in the DASHBOARD component: Cannot read property 'toLowerCase' of undefined

I've tried to send the data without any filtering directly to TASKS.js and this is working correctly (all the tasks are shown). But as soon as I pass newArray to , it doesn't work anymore.

Also, when logging task.title in tasks.filter function in the DASHBOARD component, it shows all the data (with a little delay because the data is coming from 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

回答1:


Lint your App.css for any errors.

I encountered this message. I traced it to a CSS include:

.box-table { border-color:; border: 1px solid #dbdad8; }

The missing value of border-color: caused npm run build to fail.

Interestingly, the same file contained

.submenu-button.submenu-opened:after { background:; }

which caused no problems at all.



来源:https://stackoverflow.com/questions/55886795/cannot-read-property-tolowercase-of-undefined-react-firestore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!