admin管理员组文章数量:1392002
I'm new to React and am trying to figure out how to make a phonebook. I've gotten quite far but I'm having an issue I can't solve. I'm using React Hooks.
Everything works fine, except for when I call the setNewNumber('')
and setNewName('')
functions at the end of addPerson()
, just before the filteredEntries
const.
I want to reset the input fields in the form to empty strings (''
) once the other code inside addPerson()
is done running, but it seems like the two functions are never called since the value for newName
and newNumber
don't change to ''
(instead they keep the values the user added). However, my other useState functions (setPersons()
and setFilteredPersons()
) work inside addPerson()
...
I've tried reading the documentation and asking around but haven't found a solution. I'd be very grateful for any clues/help!
import React, { useState } from 'react'
import Person from './ponents/Person'
const App = () => {
const [ persons, setPersons ] = useState([
{ name: 'Cat', number: '111' },
{ name: 'Dog', number: '222' },
{ name: 'Horse', number: '333' },
{ name: 'Owl', number: '444' }
])
const [filteredPersons, setFilteredPersons] = useState([...persons])
const [ newName, setNewName ] = useState('')
const [ newNumber, setNewNumber ] = useState('')
const addPerson = (event) => {
event.preventDefault()
const createPerson = () => {
const personObject = {
name: newName,
number: newNumber,
}
setPersons([...persons, personObject])
setFilteredPersons([...persons, personObject]) //varför går det inte att bara köra [...persons?]
}
const upperCaseNewName = newName.toUpperCase()
let doubleName
persons.map(person => {
const upperCasePerson = person.name.toUpperCase()
if(upperCaseNewName === upperCasePerson) {
doubleName = upperCasePerson
}
return doubleName
})
if (doubleName === undefined) {
createPerson()
} else if(doubleName === upperCaseNewName) {
alert(`${newName} is already in the phonebook`)
}
setNewName('')
setNewNumber('')
}
const filterEntries = event => {
let filtered = persons.filter(person => {
return person.name.toUpperCase().indexOf(event.target.value.toUpperCase()) !== -1
})
setFilteredPersons(filtered)
}
const renderPersons = () => filteredPersons.map(person =>
<Person key={person.name} name={person.name} number={person.number}/>
)
return (
<div>
<h2>Phonebook</h2>
<p>Filter entries:</p> <input onChange={(event) => filterEntries(event)}/>
<form>
<div>
name: <input onChange={(event) => setNewName(event.target.value)}/>
<br/>
phone: <input onChange={(event) => setNewNumber(event.target.value)}/>
</div>
<div>
<button type="submit" onClick={addPerson}>add</button>
</div>
</form>
<h2>Numbers</h2>
{renderPersons()}
</div>
)
}
export default App
The person ponent at the top just contains this code:
import React from 'react'
const Person = (props) => {
return(
<>
<p>{props.name} {props.number}</p>
</>
)
}
export default Person
I'm new to React and am trying to figure out how to make a phonebook. I've gotten quite far but I'm having an issue I can't solve. I'm using React Hooks.
Everything works fine, except for when I call the setNewNumber('')
and setNewName('')
functions at the end of addPerson()
, just before the filteredEntries
const.
I want to reset the input fields in the form to empty strings (''
) once the other code inside addPerson()
is done running, but it seems like the two functions are never called since the value for newName
and newNumber
don't change to ''
(instead they keep the values the user added). However, my other useState functions (setPersons()
and setFilteredPersons()
) work inside addPerson()
...
I've tried reading the documentation and asking around but haven't found a solution. I'd be very grateful for any clues/help!
import React, { useState } from 'react'
import Person from './ponents/Person'
const App = () => {
const [ persons, setPersons ] = useState([
{ name: 'Cat', number: '111' },
{ name: 'Dog', number: '222' },
{ name: 'Horse', number: '333' },
{ name: 'Owl', number: '444' }
])
const [filteredPersons, setFilteredPersons] = useState([...persons])
const [ newName, setNewName ] = useState('')
const [ newNumber, setNewNumber ] = useState('')
const addPerson = (event) => {
event.preventDefault()
const createPerson = () => {
const personObject = {
name: newName,
number: newNumber,
}
setPersons([...persons, personObject])
setFilteredPersons([...persons, personObject]) //varför går det inte att bara köra [...persons?]
}
const upperCaseNewName = newName.toUpperCase()
let doubleName
persons.map(person => {
const upperCasePerson = person.name.toUpperCase()
if(upperCaseNewName === upperCasePerson) {
doubleName = upperCasePerson
}
return doubleName
})
if (doubleName === undefined) {
createPerson()
} else if(doubleName === upperCaseNewName) {
alert(`${newName} is already in the phonebook`)
}
setNewName('')
setNewNumber('')
}
const filterEntries = event => {
let filtered = persons.filter(person => {
return person.name.toUpperCase().indexOf(event.target.value.toUpperCase()) !== -1
})
setFilteredPersons(filtered)
}
const renderPersons = () => filteredPersons.map(person =>
<Person key={person.name} name={person.name} number={person.number}/>
)
return (
<div>
<h2>Phonebook</h2>
<p>Filter entries:</p> <input onChange={(event) => filterEntries(event)}/>
<form>
<div>
name: <input onChange={(event) => setNewName(event.target.value)}/>
<br/>
phone: <input onChange={(event) => setNewNumber(event.target.value)}/>
</div>
<div>
<button type="submit" onClick={addPerson}>add</button>
</div>
</form>
<h2>Numbers</h2>
{renderPersons()}
</div>
)
}
export default App
The person ponent at the top just contains this code:
import React from 'react'
const Person = (props) => {
return(
<>
<p>{props.name} {props.number}</p>
</>
)
}
export default Person
Share
Improve this question
asked Oct 15, 2019 at 15:17
JumpyWizardJumpyWizard
251 silver badge6 bronze badges
3 Answers
Reset to default 3Your ponents are not actually tied to your state values. You need them to be "controlled." Check out the docs for more examples :)
https://reactjs/docs/forms.html#controlled-ponents
<input value={newName} onChange={event => setNewName(event.target.value)} />
The reset is working correctly. What you forgot to do is add the value
to each input. Without the value
attribute the input is considered an uncontrolled ponent. By the sounds of it, you're looking to control the value via code.
Change
<div>
name: <input onChange={event => setNewName(event.target.value)} />
<br />
phone: <input onChange={event => setNewNumber(event.target.value)} />
</div>
to
<div>
name: <input value={newName} onChange={event => setNewName(event.target.value)} />
<br />
phone: <input value={newNumber} onChange={event => setNewNumber(event.target.value)} />
</div>
Codesandbox Demo
You have missed adding value
attribute to input
and thus your ponent is not the "Controlled" ponent.
You can read more here.
Changes needed
<input
value={newName}
onChange={event => setNewName(event.target.value)}
/>
<br />
phone:
<input
value={newNumber}
onChange={event => setNewNumber(event.target.value)}
/>
Codesandbox Link: https://codesandbox.io/s/crimson-frog-ecp98
Hope this Helps!
本文标签: javascriptReact hooks Can39t update state inside function componentStack Overflow
版权声明:本文标题:javascript - React hooks: Can't update state inside function component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744774338a2624534.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论