简体   繁体   中英

React Hook error in array handing in useEffect() and setState does not set the state

I'm having two problems in this code. The first is in the second useEffect. For the reason that I don't understand the useEffect stops working every now and then and causes an error "Cannot read property 'toLowerCase'". Removing the toLowerCase does not solve the problem, but the whole array handling seems to be impossible at that time.

The other problem is in the function addName. setNewName does not set newName. That one I've tried in various kinds of forms, such as setNewName(...newName, {name: '', number: ''}), setNewName('') inside.then and else as well as outside else.

...

import React, {useState, useEffect} from 'react'
import Filter from './components/Filter'
import PersonForm from './components/PersonForm'
import Persons from './components/Persons'
import personService from './services/person'


const App = () => {
  const [person, setPerson] = useState([])
  const [newName, setNewName] = useState({name: '', number: ''})
  const [filteredPerson, setFilteredPerson] = useState([''])
  const [searchTerm, setSearchTerm] = useState('')

  useEffect(() => {
    personService
      .getAll()
      .then(initialPersons => {
        setPerson(initialPersons)
      })
  }, [])


  useEffect( () => { 
    const results = person.filter( p =>
      p.name.toLowerCase().includes(searchTerm) )
    
    setFilteredPerson(results)
  },[person,filteredPerson] )


  const addName = (event) => {
    event.preventDefault() 
    const nameObject = {
      name: newName.name,
      number: newName.number
    }
  
    if (person.some(p => p.name === newName.name)  
    ) {
      window.alert(`${newName.name} is already added to phonebook`)    
    }
    else { 
      personService
      .create(nameObject)
      .then(returnedPerson => {
        setPerson(person.concat(returnedPerson))
        setNewName({name: '', number: ''})                  
      })
      
      console.log('newName', newName.name )           
    }  
  }

  const handleAddPerson = (event) => {
    console.log('event.target.name ', event.target.name) 
    console.log('event.target.value ', event.target.value)
    setNewName({...newName,
      [event.target.name]: event.target.value
    })
  }

  const handleSearchTerm = (event) => {
    setSearchTerm(event.target.value)
  }

  return (
    <div >
      <h2>Phonebook</h2>
      <Filter searchTerm={searchTerm} onChange={handleSearchTerm} /> 

      <h3>Add a new</h3>  
      <PersonForm onSubmit={addName} onChange={handleAddPerson} />
      
      <h2>Numbers</h2>
      <Persons list={filteredPerson} />
    </div>
  );
}

export default App;

...

import axios from 'axios'
const baseUrl = 'http://localhost:3001/persons'

const getAll = () => {
    const request = axios.get(baseUrl)
    return request.then(response => response.data)
}

const create = newObject => {
    const request = axios.post(baseUrl, newObject)
    return request.then(response => response.data)
}

const update = (id, newObject) => {
    const request = axios.put(`${baseUrl}/${id}`, newObject)
    return request.then(response => response.data)
}

/*const updater = {
    getAll,
    create,
    update
}*/

export default {
    getAll,
    create,
    update
}

EDIT

Use async await in your personService so you can return response instead of return request.then(...) something like:

const getAll = async () => {
  const response = await axios.get(baseUrl);
  return response;
}

After that you can do as follows in your useEffect

useEffect(() => {
  (async () => {
    const response = await personService.getAll();
    if (response.status === 200) {
      setPerson(response.data);
      const filtered = response.data.filter(item =>
        item.name.toLowerCase().includes(searchTerm)
      );
      setFilteredPerson([...filtered]);
    }
  })();
}, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM