#javascript #reactjs #asynchronous #promise #react-hooks
#javascript #reactjs #асинхронный #обещание #реагирующие хуки
Вопрос:
Я пытаюсь выполнить несколько действий в одной функции. Мне нужно, чтобы все они выполнялись одна за другой при отправке формы
1. Get back data (here is where the meals array is set)
2. Check the length of the meals array
3. Append a slide if the length of the array is longer than 1
4. Slide to that new slide if meals length is indeed greater than 1
Я пытаюсь выполнять обратные вызовы и асинхронные функции, и это все еще не работает. При отправке формы устанавливается массив meals. Затем, если я отправлю запрос снова, проверяется массив длины блюда и добавляется слайд, если оператор if / else имеет значение true.
Пожалуйста, помогите мне! Я приму любое решение, которое работает — обещания, обратные вызовы и т. Д.
Вот код для первой функции:
const handleSearch = (e) => {
e.preventDefault();
if (searchVal.trim() !== '') {
let foodSearch = searchVal.trim().replace(/ /g, ' ')
databaseFetch(`${BASE_URL}search.php?s=${foodSearch}`)
secondFunction()
} else {
setSearchVal('')
}
}
И вот вторая функция:
function secondFunction() {
if (meals.length > 1) {
slide1Horizontal.appendSlide(`<div class="swiper-slide">${ReactDOMServer.renderToString(<SearchResults />)}</div>`)
slide1Horizontal.slideTo(2, 1000)
}
Вот исходная функция выборки:
const databaseFetch = async foodToSearch => {
setLoading(true)
let returned = await (await fetch(foodToSearch));
if (returned.ok) {
let result = await returned.json()
//console.log(result)
setMeals(
result.meals !== null
? [...result.meals]
: []
)
//console.log(meals)
} else {
setError({
error: true,
statusCode: returned.status,
statusText: returned.statusText
})
}
setLoading(false)
}
}
Комментарии:
1. Что такое
setMeals
и какова область действияmeals
переменной?2. Я использую реагирующие хуки
Ответ №1:
Вам кажется, что вам нужно сделать вашу функцию handleSearch асинхронной функцией и ожидать получения вашей БД с помощью синтаксиса async / await .
https://javascript.info/async-await
Проблема также заключается в том, что вы ссылаетесь на переменную с отслеживанием состояния «питание» в той же функции, в которой она установлена, и вы ожидаете получить обновленное значение. Что вам нужно сделать, это вернуть питание в компонент databaseFetch , а затем передать возвращаемое значение databaseFetch в secondFunction в качестве параметра. Это должно дать вам обновленное значение
const handleSearch = (e) => {
e.preventDefault();
if (searchVal.trim() !== '') {
let foodSearch = searchVal.trim().replace(/ /g, ' ')
databaseFetch(`${BASE_URL}search.php?s=${foodSearch}`)
secondFunction()
} else {
setSearchVal('')
}
const databaseFetch = async foodToSearch => {
setLoading(true)
let returned = await (await fetch(foodToSearch));
if (returned.ok) {
let result = await returned.json()
//console.log(result)
return (
result.meals !== null
? [...result.meals]
: []
)
//console.log(meals)
} else {
setError({
error: true,
statusCode: returned.status,
statusText: returned.statusText
})
}
setLoading(false)}
function secondFunction(mealsFromDb) {
if (mealsFromDb.length > 1) {
slide1Horizontal.appendSlide(`<div class="swiper-slide">${ReactDOMServer.renderToString(<SearchResults />)}</div>`)
slide1Horizontal.slideTo(2, 1000)
}
Комментарии:
1. Это решение создает ту же проблему.
2. Тот же результат. Всякий раз, когда я отправляю форму, массив meals отстает на 1 итерацию.
Ответ №2:
Почему бы не добавить вторую функцию в выборку базы данных?
const databaseFetch = async foodToSearch => {
setLoading(true)
let returned = await (await fetch(foodToSearch));
if (returned.ok) {
let result = await returned.json()
// ADD SECOND FUNCTION HERE TO ENSURE THAT IT RUNS AFTER DATA FETCH
secondFunction(result);
return (
result.meals !== null
? [...result.meals]
: []
)
//console.log(meals)
} else {
setError({
error: true,
statusCode: returned.status,
statusText: returned.statusText
})
}
setLoading(false)}