我的状态不断将空元素添加到其数组中
对于setperson,我的二传手似乎一直在没有明显的原因中将空元素添加到其数组中。当我更新用户的电话号码时,我正在尝试使我的电话号码列表立即更新,但它坚持使用旧数字。每当我将逻辑应用以立即进行数字更新时,它会将空元素添加到我的数组中,并且不会立即更新。这是每个单独组件的代码:
app.js
import { useEffect, useState, useRef} from 'react'
import PersonForm from './components/PersonForm'
import Display from './components/Display'
import Filter from './components/Filter'
import phoneService from './services/information'
const App = () => {
const [errorMessage, setErrorMessage] = useState('')
const [persons, setPersons] = useState('')
const [newName, setNewName] = useState('')
const [newNumber, setNewNumber] = useState('')
const [filter, setFilter] = useState('')
const [filterChecker, setFilterChecker] = useState('')
useEffect(() => {
phoneService.getAll()
.then(people => setPersons(people))
}, [])
const handleSubmit = (e) => {
e.preventDefault();
const copy = [...persons]
const foundNameOrNot = persons.some(el => el.name === newName)
const foundNumberOrNot = persons.some(el => el.number === newNumber)
const eachPersonsID = persons.map(person => person.id)
const newObj = {
name: newName,
number: newNumber,
id: Math.max(eachPersonsID) + 1
}
if (foundNameOrNot) {
if(window.confirm(`${newName} is added to phonebook, replace the old number with a new one.`)) {
const indexFinder = persons.filter(person => person.name === newName)
newObj.id = indexFinder[0].id
copy[indexFinder[0].id] = newObj
phoneService.update(indexFinder[0].id, newObj)
.then(res => {
setErrorMessage(`Successfully updated ${newName}s number`)
setPersons([copy])})
.catch(err => {
setErrorMessage(`Information on ${newName} has already been removed`)
setFilterChecker(filterChecker.filter(filter => filter !== newName))})
}
} else if (foundNumberOrNot) {
alert(`${newNumber} belongs to someone else`)
} else {
phoneService.create(newObj).then(res => setPersons([...persons, newObj]))
}
}
const handleFilter = (e) => {
console.log(persons)
setFilter(e.target.value)
const allNames = persons.map(person => person.name)
setFilterChecker(allNames.filter(name => name.toLowerCase().indexOf(filter.toLowerCase()) !== -1))
}
return (
<div>
<h1 className='error'>{errorMessage ? errorMessage : ''}</h1>
<h2>Phonebook</h2>
<Filter filter={filter} handleFilter={handleFilter}/>
<h2>add a new</h2>
<form onSubmit={handleSubmit}>
<PersonForm newName={newName} newNumber={newNumber} setNewName={setNewName} setNewNumber={setNewNumber}/>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
<Display filterChecker={filterChecker} persons={persons} setPersons={setPersons} setFilterChecker={setFilterChecker} errorMessage={errorMessage} setErrorMessage={setErrorMessage} />
</div>
)
}
export default App
display.js
import phoneService from '../services/information'
import axios from 'axios'
import { useState } from 'react'
const handleDelete = (i, persons, setPersons, name2, setFilterChecker, errorMessage, setErrorMessage) => {
if (window.confirm(`delete ${name2} ?`)) {
const newArrayOfPeople = persons.filter(person => person.name !== name2)
const newArrayOfNames = newArrayOfPeople.map(person => person.name)
setFilterChecker(newArrayOfNames)
setPersons(newArrayOfPeople)
phoneService.remove(persons[i].id)
setErrorMessage(`You have successfully deleted ${name2} from the list.`)
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const Display = ({filterChecker, persons, setPersons, setFilterChecker, errorMessage, setErrorMessage}) => {
const copy = [...persons]
const findNumbers = []
const findNames = []
for (let j = 0; j < copy.length; j++) {
if (copy[j]?.name && !findNames.includes(copy[j]?.name)) {
findNames.push(copy[j].name)
}
}
for (let i = 0; i < copy.length; i++) {
if (copy[i]?.number && !findNumbers.includes(copy[i]?.number)) {
findNumbers.push(copy[i]?.number)
}
}
if (filterChecker) {
return (
findNames.map((name, i) => <div><nobr key={name}>{name} {findNumbers[i]}</nobr> <button onClick={() => handleDelete(i, persons, setPersons, name, setFilterChecker, errorMessage, setErrorMessage)}>delete</button></div>)
)
} else {
return ''
}
}
export default Display
filter.js
const Filter = ({filter, handleFilter}) => {
return <p>filter shown with <input value={filter} onChange={handleFilter}/></p>
}
export default Filter
personform.js
import axios from 'axios';
import phoneService from '../services/information'
const PersonForm = ({newName, newNumber, setNewName, setNewNumber}) => {
return (
<div>
name: <input value={newName} onChange={(e) => setNewName(e.target.value)}/>
number: <input value={newNumber} onChange={(e) => setNewNumber(e.target.value)}/>
</div>
)
}
export default PersonForm
inovy.js
import axios from "axios"
const baseUrl = 'http://localhost:3002/numbers'
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 remove = (id) => {
const request = axios.delete(`${baseUrl}/${id}`)
return request.then(res => res.data)
}
export default { getAll, create, update, remove, baseUrl }
我的json服务器“ db.json”,
{
"numbers": [
{
"name": "uvaldo",
"number": "20",
"id": 6
},
{
"name": "uvaldo zumaya",
"number": "24",
"id": 7
},
{
"name": "uvaldo zumaya d",
"number": "26",
"id": 8
}
]
}
每当我尝试更新“ uvaldo”电话号码到22 21然后引发错误,此图片是在我点击“添加”之前以避免程序崩溃...
My setter, for SetPersons, seems to keep adding empty elements into its array for no apparent reason. I am trying to make my phone number list update instantaneously when I update a user's number but it sticks with the old number. Whenever I apply the logic to possibly make the number update instantly, it adds empty elements into my array instead and does not update instantly. Here is the code for each separate component:
App.js
import { useEffect, useState, useRef} from 'react'
import PersonForm from './components/PersonForm'
import Display from './components/Display'
import Filter from './components/Filter'
import phoneService from './services/information'
const App = () => {
const [errorMessage, setErrorMessage] = useState('')
const [persons, setPersons] = useState('')
const [newName, setNewName] = useState('')
const [newNumber, setNewNumber] = useState('')
const [filter, setFilter] = useState('')
const [filterChecker, setFilterChecker] = useState('')
useEffect(() => {
phoneService.getAll()
.then(people => setPersons(people))
}, [])
const handleSubmit = (e) => {
e.preventDefault();
const copy = [...persons]
const foundNameOrNot = persons.some(el => el.name === newName)
const foundNumberOrNot = persons.some(el => el.number === newNumber)
const eachPersonsID = persons.map(person => person.id)
const newObj = {
name: newName,
number: newNumber,
id: Math.max(eachPersonsID) + 1
}
if (foundNameOrNot) {
if(window.confirm(`${newName} is added to phonebook, replace the old number with a new one.`)) {
const indexFinder = persons.filter(person => person.name === newName)
newObj.id = indexFinder[0].id
copy[indexFinder[0].id] = newObj
phoneService.update(indexFinder[0].id, newObj)
.then(res => {
setErrorMessage(`Successfully updated ${newName}s number`)
setPersons([copy])})
.catch(err => {
setErrorMessage(`Information on ${newName} has already been removed`)
setFilterChecker(filterChecker.filter(filter => filter !== newName))})
}
} else if (foundNumberOrNot) {
alert(`${newNumber} belongs to someone else`)
} else {
phoneService.create(newObj).then(res => setPersons([...persons, newObj]))
}
}
const handleFilter = (e) => {
console.log(persons)
setFilter(e.target.value)
const allNames = persons.map(person => person.name)
setFilterChecker(allNames.filter(name => name.toLowerCase().indexOf(filter.toLowerCase()) !== -1))
}
return (
<div>
<h1 className='error'>{errorMessage ? errorMessage : ''}</h1>
<h2>Phonebook</h2>
<Filter filter={filter} handleFilter={handleFilter}/>
<h2>add a new</h2>
<form onSubmit={handleSubmit}>
<PersonForm newName={newName} newNumber={newNumber} setNewName={setNewName} setNewNumber={setNewNumber}/>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
<Display filterChecker={filterChecker} persons={persons} setPersons={setPersons} setFilterChecker={setFilterChecker} errorMessage={errorMessage} setErrorMessage={setErrorMessage} />
</div>
)
}
export default App
Display.js
import phoneService from '../services/information'
import axios from 'axios'
import { useState } from 'react'
const handleDelete = (i, persons, setPersons, name2, setFilterChecker, errorMessage, setErrorMessage) => {
if (window.confirm(`delete ${name2} ?`)) {
const newArrayOfPeople = persons.filter(person => person.name !== name2)
const newArrayOfNames = newArrayOfPeople.map(person => person.name)
setFilterChecker(newArrayOfNames)
setPersons(newArrayOfPeople)
phoneService.remove(persons[i].id)
setErrorMessage(`You have successfully deleted ${name2} from the list.`)
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const Display = ({filterChecker, persons, setPersons, setFilterChecker, errorMessage, setErrorMessage}) => {
const copy = [...persons]
const findNumbers = []
const findNames = []
for (let j = 0; j < copy.length; j++) {
if (copy[j]?.name && !findNames.includes(copy[j]?.name)) {
findNames.push(copy[j].name)
}
}
for (let i = 0; i < copy.length; i++) {
if (copy[i]?.number && !findNumbers.includes(copy[i]?.number)) {
findNumbers.push(copy[i]?.number)
}
}
if (filterChecker) {
return (
findNames.map((name, i) => <div><nobr key={name}>{name} {findNumbers[i]}</nobr> <button onClick={() => handleDelete(i, persons, setPersons, name, setFilterChecker, errorMessage, setErrorMessage)}>delete</button></div>)
)
} else {
return ''
}
}
export default Display
Filter.js
const Filter = ({filter, handleFilter}) => {
return <p>filter shown with <input value={filter} onChange={handleFilter}/></p>
}
export default Filter
PersonForm.js
import axios from 'axios';
import phoneService from '../services/information'
const PersonForm = ({newName, newNumber, setNewName, setNewNumber}) => {
return (
<div>
name: <input value={newName} onChange={(e) => setNewName(e.target.value)}/>
number: <input value={newNumber} onChange={(e) => setNewNumber(e.target.value)}/>
</div>
)
}
export default PersonForm
information.js
import axios from "axios"
const baseUrl = 'http://localhost:3002/numbers'
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 remove = (id) => {
const request = axios.delete(`${baseUrl}/${id}`)
return request.then(res => res.data)
}
export default { getAll, create, update, remove, baseUrl }
My json-server "db.json"
{
"numbers": [
{
"name": "uvaldo",
"number": "20",
"id": 6
},
{
"name": "uvaldo zumaya",
"number": "24",
"id": 7
},
{
"name": "uvaldo zumaya d",
"number": "26",
"id": 8
}
]
}
Whenever I try to update "uvaldo" phone number to 22, it just stays at 21 then throws errors, this picture is before I hit "add" to avoid the program crashing...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
逻辑存在一些问题,您可以在其中更新
persons
。试试看:
添加空元素的原因是用于放置
newObj
的索引大于数组的大小:另请注意,
person.id
dik不一定意味着它们在数组Persons
的索引中。There are issues with the logic where you update
persons
.Try this instead:
The reason why it was adding empty elements is that the index used to place
newObj
was greater than the size of the array:Also note that
person.id
does not necessarily mean that they are in that index of the arraypersons
.