#javascript #reactjs #async-await
#javascript #reactjs #асинхронное ожидание
Вопрос:
У меня есть алгоритм, который можно использовать во многих местах в моем приложении React. По этой причине мне нужно, чтобы он был асинхронным, чтобы не задерживать рендеринг компонентов.
Кроме того, если в цикле сокращения есть ошибка, мне нужно остановить функцию и вернуть значение null. Формат try / catch кажется подходящим. Однако React утверждает, что:
Объекты недопустимы как дочерние элементы React (найдено: [обещание объекта]). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив.
Проблема не в моем алгоритме, а в его асинхронной природе. Я написал этот очень простой пример, который вызывает точно такую же ошибку:
async function test(name){
try{
if(!name) {
throw new Error
}
const formattedName = name.toUppercase()
return formattedName
}
catch{
return "error"
}
}
export default function App() {
return (
<>
{test("joe")}
</>
);
}
Как это исправить?
Комментарии:
1. Если вы
await
не используете асинхронную функцию, она вернет объект promise, а не значение youreturn
.2. Даже при использовании const formattedName = await name.toUpperCase() ошибка остается.
3. Да, await не останавливает функцию, чтобы продолжать возвращать обещание
4. » По этой причине мне нужно, чтобы он был асинхронным, чтобы не задерживать рендеринг компонентов». — нет, это не так, как это работает. Ваш алгоритм не является асинхронным, и он не должен быть помечен как
async
. И в настоящее время ваш компонент не может обрабатывать рендеринг без результата алгоритма — это то, что вам нужно будет исправить.
Ответ №1:
Я не знаю, каков ваш вариант использования, но, вероятно, вы просто хотите иметь состояние в React, которое содержит имя или любое значение, которое вы хотите, а затем отображать это значение, если оно доступно, что-то вроде:
const [name, setName] = useState("")
async function test(name){
try{
if(!name) {
throw new Error
}
const formattedName = name.toUppercase()
setName(formattedName)
}
catch{
return "error"
}
}
export default function App() {
return (
<>
{name}
</>
);
}
РЕДАКТИРОВАТЬ: Предположим, что у вас есть эта js
функция в utils
папке или что-то еще, что выполняет весь упомянутый вами синтаксический анализ. Вы можете рассматривать это как асинхронный вызов API, то, что вам нужно, находится в вашем компоненте React (предположим, при первом рендеринге), следующее:
const [data, setData] = useState(...)
useEffect(async () => {
const data = await callToYourParsingFunctionThatIsAsync();
setData(data);
}, [])
И затем вы отображаете все, что вам нужно, из этой data
переменной
Комментарии:
1. Нет, это функция трансляции за пределами области действия React. Он проверяет огромный файл json и возвращает правильный динамический перевод. Поэтому я не могу использовать какое-либо состояние.
2. Так в чем проблема? Вы можете продолжать устанавливать состояние. Редактирую мой ответ прямо сейчас
3. Проблема в том, что если у меня будет 600 вызовов этой функции в моем приложении, мне понадобится так много состояний. Это не чистая архитектура.
4. Я не совсем понимаю ваш вариант использования, но у вас может быть HOC (компонент высокого порядка) или поставщик контекста, который будет сохранять только одно состояние, и вы можете поделиться функцией трансляции с тем, кому это нужно. Но ответ таков. Пожалуйста, отметьте как правильный ответ, если он подходит
Ответ №2:
import React, { useState } from "react";
export default function App() {
const [name, setName] = useState("");
async function test(innerName) {
if (innerName === name) {
return;
}
try {
if (!innerName) {
throw new Error();
}
const formattedName = innerName;
setName(formattedName);
} catch {
return "error";
}
}
test("Joe");
return <>{"Testing : " name}</>;
}
Вам необходимо использовать состояние для обновления рендеринга при будущем событии во времени. Пример кода выглядит так, как указано выше.
Комментарии:
1. Но если у меня будет 600 вызовов этой функции в моем приложении, мне понадобится так много состояний… Я думаю, мне нужно найти другой способ обработки ошибок внутри reduce.
2. @DoneDeal0 ЧТО делает эта функция? Как вы думаете, почему это дорого, но все равно вызывает его 600 раз?
3. это функция перевода, которая проверяет огромный файл json и возвращает правильную динамическую строку на основе предоставленного ключа и параметров. Я не могу добавлять состояние каждый раз, когда я его использую, это безумие.