20210916 - Cannot read property 'name' of null
2021-09-16 00:00:00
# React
# Half-solved
起因:
做phonebook的时候发现一个bug:后端新建一个联系人,前端刷新,更新最新的phonebook,并返回后端删除刚刚新建的联系人,前端修改这个联系人(实际上数据库中已经不存在)的信息,submit后报如下错误:

前端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const samePerson = persons.find(person => person.name === newName) const changedPerson = {...samePerson, number: newNumber}
personService .update(samePerson.id, changedPerson) .then(returnedPerson => { **console.log(returnedPerson) setPersons(persons.map(person => person.id === samePerson.id ? returnedPerson : person)) setNewName('') setNewNumber('') setError(false) setMessage( `Updated ${returnedPerson.name}'s number` ) setTimeout(() => { setMessage(null) }, 5000) }) .catch(error => { setMessage( `Information of ${samePerson.name} has already been removed from server` ) setTimeout(() => { setMessage(null) }, 5000); setPersons(persons.filter(person => person.name !== newName)) setError(true) })
|
修改前的后端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| app.put('/api/persons/:id', (req, res, next) => { const body = req.body const person = { name: body.name, number: body.number, }
Person.findByIdAndUpdate(req.params.id, person, {new: true}) .then(updatedPerson => { **console.log(updatedPerson) res.json(updatedPerson) }) .catch(error => next(error)) })
|
先debug前端代码,发现接收到的put请求的返回值returnedPerson
为null,按理说这种情况promise应该rejected,进入catch,并且输出报错的message。
debug后端代码,发现更新数据后返回的updatedPerson
也为null,于是加了个判断,不为null就返回,为null就报错,返回给前端就是rejected,进入catch,并输出报错的message。
修改后的后端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| app.put('/api/persons/:id', (req, res, next) => { const body = req.body const person = { name: body.name, number: body.number, }
Person.findByIdAndUpdate(req.params.id, person, {new: true}) .then(updatedPerson => { console.log(updatedPerson) if (updatedPerson) { res.json(updatedPerson) } else { res.status(404).end() } }) .catch(error => next(error)) })
|
React App可以正常运行

这个情况和之前在GET请求中用findByID()
获取单个document很相似,那个案例中也是对返回值作了判断,如果是id合法但未找到信息(被删除或者本来就不存在),就返回null(没测试过,但理论上应该是这样),而id不合法直接进入catch返回error。所以大概是mongoose的findXXX方法的特性??
20210915 - 两种情况两种状态码
另(这是我发现这个错误之前的前端代码):
这段代码让我疑惑的点是,为什么在setNewName('')
之后,setMessage()
仍然可以获得newName
的值?之前写的时候竟然没注意到。。。
(关于这个,听过一种说法是,多个setState的时候,可能会组团一起更新。。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| personService .update(samePerson.id, changedPerson) .then(returnedPerson => { console.log(returnedPerson) setPersons(persons.map(person => person.id === samePerson.id ? returnedPerson : person)) setNewName('') setNewNumber('') setError(false) setMessage( `Updated ${**newName**}'s number` ) setTimeout(() => { setMessage(null) }, 5000) }) .catch(error => { setNewName('') setNewNumber('') setMessage( `Information of ${**newName**} has already been removed from server` ) setTimeout(() => { setMessage(null) }, 5000); setPersons(persons.filter(person => person.name !== newName)) setError(true) })
|
贴一下相关的问答和参考:
为什么调用react setState方法不会立即改变状态?
React Lifecycle Methods diagram
React.Component - React
React setState not Updating Immediately