Как реализовать React HTTP запросы на удаление без идентификатора? - PullRequest
1 голос
/ 19 октября 2019

Когда на сервере генерируются идентификаторы для документов, как клиент может правильно отправлять HTTP-запросы на удаление? Поскольку для запросов HTTP Delete требуется идентификатор документа для маршрутизации на сервер, но идентификаторы генерируются на сервере, как веб-интерфейс может знать сгенерированные идентификаторы?

На моем сервере:

let persons = [ // my "database"
    {
    "name": "Arto Hellas",
    "number": "040-123456",
    "id": 1
    },
    {
    "name": "test1",
    "number": "111-111-1111",
    "id": 4168 //GENERATED AFTER RECEIVING AN HTTP POST REQUEST
    },
    {
    "name": "test2",
    "number": "222-222-2222",
    "id": 839 //GENERATED AFTER RECEIVING AN HTTP POST REQUEST
    }

];

app.delete('/api/persons/:id', (req,res) => {
    let id = Number(req.params.id);
    persons = persons.filter(person => person.id !== id);
    res.json(persons);
});

const generateId = () => {
    return Math.floor(Math.random() * 10000); //0 to 9999
}

app.post('/api/persons', (req,res) => {
    let body = req.body;

    let newPerson = {
        name: body.name,
        number: body.number,
        id: generateId()
    }

    persons = persons.concat(newPerson);
    res.json(persons);
});

Когда мой веб-интерфейс создает запрос HTTP Post к бэкэнду, он отправляет имя и номер. Бэкэнд получает запрос Post и создает объект JS с Name, Number, а также генерирует для него идентификатор, а затем добавляет его в мой массив «database».

Вот мой рассматриваемый компонент React с возможностью удаления,

const PhoneBookEntry = ({ name, number, persons, setPersons}) => {

    const deletePerson = () => {
        phonebookComm
            .delPerson(id) // *** how can my frontend determine the IDs generated in the backend?
            .then( res => {
                //updating my application's persons state
                persons.splice(persons.findIndex(element => element.name === name), 1 ); 
                setPersons(persons.map(person => person.name !== name ? person : null));                                                    
            })
            .catch( error => {
                console.log('error', error);
            })
    }

    return (
        <div>
            <div className="personAndDelBtn">{name} {number} </div>
            <button className="personAndDelBtn" onClick={deletePerson}>delete</button>
        </div>
    );
}

Где phonebookComm использует axios:

const delPerson = id => {
    return axios.delete(`${baseUrl}/${id}`).then(res => res.data);
}

Как получить идентификаторы из бэкэнда, дляHTTP-запросы на удаление в веб-интерфейсе?

Поскольку бэкэнд генерирует идентификатор для каждого документа, веб-интерфейс не знает идентификатора документа. Когда веб-интерфейсу необходимо отправить HTTP-запрос на удаление, как он может узнать, какой идентификатор использовать?

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

Возможно, вам нужно обновить вновь созданного пользователя после успешного выполнения запроса POST: у вас есть идентификатор, поскольку сервер отправляет вам вновь созданного пользователя в ответе POST (с идентификатором):

app.post('/api/persons', (req,res) => {
    let body = req.body;

    let newPerson = {
        name: body.name,
        number: body.number,
        id: generateId()
    }

    persons = persons.concat(newPerson);
    res.json(persons);
});
1 голос
/ 19 октября 2019

Ваш компонент PhoneBookEntry - это строка в списке людей, не так ли? Думаю, у вас должен быть какой-то способ получить список этого человека с вашего сервера. Примерно так:

app.get('/api/persons', (req,res) => {
    res.json(persons);
});

Вы должны перезагрузить список людей с сервера после каждого действия редактирования, например удаления. Не рекомендуется управлять локальной базой данных и базой данных сервера аналогичным образом.

Я предлагаю перенести метод удаления из компонента PhoneBookEntry.

const PhoneBookEntry = ({ name, number, onDelete}) => {
    return (
        <div>
            <div className="personAndDelBtn">{name} {number} </div>
            <button className="personAndDelBtn" onClick={onDelete}>delete</button>
        </div>
    );
}

И определить методы удаления и выборки в компоненте верхнего уровня(список людей). Я использую React Hooks useState useCallback и useEffect. Они великолепны, примерьте их!

const PhoneBook = () => {

// book state
    const [list, setList] = useState([]);
// loading flag
    const [loading, setLoading] = useState(true);

    const fetch = useCallback(() => fetchPersons().then((res) => setList(res), [])

    const deletePerson = useCallback((id) => delPerson(id).then(() => fetch()), [])

//this will run fetch after the component was mounted and rendered in the first time
    useEffect(() => {
        fetch().then(() => setLoading(false))
    }, [])

    if (loading) {
        return <div>Loading contacts... </div>
    }

    return <ul>
        {list.map((person) => {
            return <li>
                <PhoneBookEntry name={person.name} number={person.number} onDelete={() => deletePerson(person.id)}
                                key={person.id}/>
            </li>
        })}
    </ul>

}

Вы можете определить метод fetch следующим образом

const fetch = () => axios.get(`${baseUrl}`)
...