#reactjs #axios #react-hooks
#reactjs #axios #react-перехваты
Вопрос:
Я извлекаю список активных задач из Todoist
const [activeTasks, setActiveTasks] = useState([]);
useEffect(() => {
axios
.get("https://api.todoist.com/rest/v1/tasks?project_id=111234345", {
headers: {
Authorization: "Bearer xxxAuthorisationCodexxx",
},
})
.then((res) => setActiveTasks(res.data));
}, []);
Обработайте результаты.
const [allTasks, setAllTasks] = useState([]); // flat list of all tasks
const [nestedAllTasks, setNestedAllTasks] = useState([]); // Nested list of all tasks
useEffect(() => {
let tasks = [];
activeTasks.map((task) =>
tasks.push({
id: task.id,
parent_id: task.parent_id,
content: task.content,
priority: task.priority,
comments: [],
complete: false,
})
);
setAllTasks(tasks);
}, [activeTasks, labels]);
Затем я пытаюсь выполнить итерацию allTasks
и добавить комментарии, для каждого комментария требуется запрос на выборку на основе идентификатора задачи, который я инкапсулировал в getComments
функцию.
const getComments = useCallback(async (task_id) => {
const comments = await axios.get(
`https://api.todoist.com/rest/v1/comments?task_id=${task_id}`,
{
headers: {
Authorization: "Bearer xxxAuthorisationCodexxx",
},
}
);
return comments;
}, []);
useEffect(() => {
let tasks = [...allTasks]; // shallow copy allTasks
const getAllComments = () => {
tasks.map(async (task) => { // loop over all tasks
await getComments(task.id) // get comments for specific task
.then((res) => (task.comments = res.data)) // add to comments property
});
};
getAllComments()
setAllTasks(tasks); // update allTasks with new array including comments
}, [getComments, allTasks]);
Я ожидал allTasks
, что теперь у меня будут комментарии из запроса на выборку, т.Е.
{
id: 1,
parent_id: undefined,
content: "Some content",
priority: 2,
labels: ["thing", "other"],
comments: [{id: 12, content: "comment1"}, {id: 22, content: "comment2"}]
complete: false,
}
Функция рендеринга в соответствии с запросом
return (
<div>
{nestedAllTasks.length !== 0 ? (
nestedAllTasks.map((task) => {
return <Task key={task.id} task={task} colours={colours} />;
})
) : (
<p>Loading active tasks...</p>
)}
</div>
);
Компонент задачи
export default function Task() {
return (
<div key={task.id}>
<div>{task.content}</div>
<div>
{task.comments
? task.comments.map((comment) => <div>{comment.content}</div>)
: null}
</div>
</div>
</div>
);
}
Когда я console.log(allTasks)
, я иногда получаю то, что ожидаю, но это никогда не отображается на экране.
Комментарии:
1. Покажите нам свой
render()
2. @k-wasilewski, функция рендеринга добавлена в соответствии с запросом.
Ответ №1:
Вы использовали then с await в последнем useEffect. Это неверно. Вы должны сохранить возвращаемое значение await в переменной.
tasks.map(async (task) => { // loop over all tasks
let res = await getComments(task.id)
task.comments = res.data
});
};
Комментарии:
1. Внесение этих изменений означает, что я могу консольно регистрировать
allTasks
и получать массив задач с данными комментариев, но это не отображается на экране! Похоже, что ему нужно сообщить о рендеринге после того, как он каким-то образом получит данные, но я думал, что для этогоuseEffect
и было нужно.