【问题标题】:Where/how do I trigger my re-render after CRUD operation?CRUD 操作后在哪里/如何触发我的重新渲染?
【发布时间】:2019-09-28 22:04:19
【问题描述】:

我制作了一个简单的 CRUD 电话簿应用程序,我可以在其中向 json-server 添加和删除人员/号码/id。 当我进行添加时,它可以正常工作并按预期重新渲染。

但是,当我尝试实现删除时,删除操作通过了数据库,但我无法重新渲染前端。

我尝试将状态组件传递给删除操作,但这似乎搞砸了。

我尝试使用 refresh() 函数来触发重新渲染,但我不能在函数内部使用 useEffect()。

这是我的主要应用

import React from 'react'
import { useState , useEffect } from 'react'
import Numbers from './Numbers'
import Person from './Person'
import PersonForm from './PersonForm'
import Filter from './Filter'
import phoneService from './services/apiMethod'

const AppPhoneBook = () => {

    const [persons, setPersons] = useState([])
    const uuidv4 = require('uuid/v4');
    const [newName, setNewName] = useState('enter a name...')
    const [newNumber, setNewNumber] = useState('enter a number...')
    const [nameToSearch, setNameToSearch] = useState('')
    const nameToShow = persons.filter(person => person.name.toLowerCase().includes(nameToSearch.toLowerCase()))

    useEffect(()=>{
        phoneService
        .getAll()
        .then(response => {
            console.log(response.data)
            setPersons(response.data)
        })
    }, [])

    const refresh = () => {
        console.log(persons)
    }

    const row = () => nameToShow.map(person => 
        <Numbers
            key = {uuidv4()}
            person = {person.name}
            number = {person.number}
            id = {person.id}
            refresh  = {refresh}
        />
    )

    const test = (event) => {
        console.log(persons.filter(person => person.name.includes(event.target.value)))
    }

    const handleNameChange = (event) => {
        setNewName(event.target.value)
        // console.log(event.target.value)
    }

    const handleNumberChange = (event) => {
        setNewNumber(event.target.value)
        // console.log(event.target.value)
    }

    const handleNameSearchChange = (event) => {
        setNameToSearch(event.target.value)
        console.log(persons.filter(person => person.name.includes(event.target.value)))
    }

    const addName = (event) => {
        event.preventDefault()
        console.log(persons.filter(person => console.log(person.name, newName))>0)

        if (persons.filter(person => person.name === newName).length>0) {
            window.alert(`${newName} is already in the phonebook !!!`)
        } else if (!newName || !newNumber) {
            window.alert('please provide both name and number')
        } else {
            const newNameObject = {
                name : newName,
                number : newNumber,
                id : uuidv4(),
            }

            phoneService
            .create(newNameObject)
            .then(response => {
                setPersons(persons.concat(newNameObject))
                setNewName('')
            })
        }
    }

    const clearNameInput = (event) => {
        event.preventDefault()
        setNewName('')
    }

    const clearNumberInput = (event) =>{
        event.preventDefault()
        setNewNumber('')
    }

    return (
        <div>
            <Filter nameToSearch={nameToSearch} handleNameSearchChange={handleNameSearchChange} test={test}/>
            <PersonForm newName={newName} handleNameChange={handleNameChange} clearNameInput={clearNameInput} 
            newNumber={newNumber} handleNumberChange={handleNumberChange} clearNumberInput={clearNumberInput} addName={addName}/>
            <Person row={row()} />
        </div>
    )
}

export default AppPhoneBook

这是我尝试实现删除操作的地方

import React, {useEffect} from 'react'
import phoneService from './services/apiMethod'

const Numbers = ({person,number,id,refresh}) => {
    const deleteName = () =>{
        window.confirm(`Delete ${person} ?`)
        const nameToDelete = {
            name : person,
            number : number,
            id : id,
        }
        console.log(nameToDelete)

        phoneService
        .deleteName(id,nameToDelete).then(response => {
            console.log(response)
            refresh()
        }

        )
    }

    return (
        <>
            <li>
                {person} : {number} (id = {id})
                <button type='button' onClick={deleteName}> delete</button>
            </li>

        </>
    )
}

export default Numbers

编辑: 我也在此处添加我的 apiMethod 以防万一

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

const getAll = () => {
    return axios.get(baseUrl)
}

const create = newObject => {
    return axios.post(baseUrl,newObject)
}

const update = (name, newObject) => {
    return axios.put(`${baseUrl}/${name}`, newObject)
}

const deleteName = (id, newObject) => {
    return axios.delete(`${baseUrl}/${id}`)
} 

export default {
    getAll : getAll,
    create : create,
    update : update,
    deleteName : deleteName
}

【问题讨论】:

  • 请展示一些代码(一个最小的可重现示例)并展示您尝试过的内容。这远非最佳 SO 问题。
  • 我的错,我还是新手提问,我不小心提交了没有提供任何代码...
  • 代码已添加,谢谢:)

标签: javascript reactjs state crud react-state-management


【解决方案1】:

我能够使用我创建的 refresh() 函数找到一种方法。如果这是最好的方法,请发表评论。

我将 {person} 传递给 refresh 函数,然后简单地过滤掉已删除的那个并将状态更新为剩余的名称数组。

...
const Numbers = ({person,number,id,refresh}) => {
    const deleteName = () =>{
        window.confirm(`Delete ${person} ?`)
        const nameToDelete = {
            name : person,
            number : number,
            id : id,
        }
        console.log(nameToDelete)

        phoneService
        .deleteName(id,nameToDelete).then(response => {
            console.log(response)
            refresh({person})
        }

        )
    }
...

刷新()

    const refresh = ({person}) => {
        console.log(persons)
        const newNameSetAfterDelete = persons.filter(eachPerson => !eachPerson.name.includes(person))
        setPersons(newNameSetAfterDelete)
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多