簡體   English   中英

反應鈎子:無法在 function 組件內更新 state

[英]React hooks: Can't update state inside function component

我是 React 的新手,正在嘗試弄清楚如何制作電話簿。 我已經走了很遠,但我遇到了一個我無法解決的問題。 我正在使用 React Hooks。

一切正常,除了當我在addPerson()末尾調用setNewNumber('')setNewName('')函數時,就在filteredEntries條目常量之前。 一旦addPerson()中的其他代碼完成運行,我想將表單中的輸入字段重置為空字符串( '' ),但似乎這兩個函數從未被調用,因為newNamenewNumber的值不會改變到'' (而不是他們保留用戶添加的值)。 但是,我的其他 useState 函數( setPersons()setFilteredPersons() )在addPerson() ...

我試過閱讀文檔並四處詢問,但沒有找到解決方案。 我將非常感謝任何線索/幫助!

import React, { useState } from 'react'
import Person from './components/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

頂部的 person 組件只包含以下代碼:

import React from 'react'

const Person = (props) => {
    return(
        <>
        <p>{props.name} {props.number}</p>
        </>
    )
}

export default Person

您的組件實際上並未與您的 state 值相關聯。 你需要他們被“控制”。 查看文檔以獲取更多示例:)

https://reactjs.org/docs/forms.html#controlled-components

<input value={newName} onChange={event => setNewName(event.target.value)} />

重置工作正常。 您忘記做的是將value添加到每個輸入。 如果沒有value屬性,輸入將被視為不受控制的組件 通過它的聲音,您正在尋找通過代碼控制值。

改變

<div>
  name: <input onChange={event => setNewName(event.target.value)} />
  <br />
  phone: <input onChange={event => setNewNumber(event.target.value)} />
</div>

<div>
  name: <input value={newName} onChange={event => setNewName(event.target.value)} />
  <br />
  phone: <input value={newNumber} onChange={event => setNewNumber(event.target.value)} />
</div>

Codesandbox 演示

您錯過了向input添加value屬性,因此您的組件不是“受控”組件。

你可以在這里閱讀更多。

需要的改變

<input
   value={newName}
   onChange={event => setNewName(event.target.value)}
/>
<br />
phone:
<input
   value={newNumber}
   onChange={event => setNewNumber(event.target.value)}
/>

Codesandbox 鏈接: https://codesandbox.io/s/crimson-frog-ecp98

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM