javascript - 即使有依赖关系,useEffect 也会无限地调度一个动作
问题描述
在useEffect
.
import React, { useEffect } from "react"
import TodoItem from "./TodoItem"
import { useDispatch, useSelector } from "react-redux"
import { getTodos } from "../redux/actions"
const TodoList = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(getTodos())
}, [getTodos])
const todos = useSelector(state => state)
return (
<div style={{ width: "75%", margin: "auto" }}>
<h3>Todo List</h3>
{console.log("mounted")}
{todos &&
todos.map(todo => {
return <TodoItem key={todo.id} title={todo.title} id={todo.id} />
})}
{todos && !todos.length && <h3>There are no tasks to do. Add one!</h3>}
</div>
)
}
export default TodoList
sagas.js:
import { call, put, takeEvery } from "redux-saga/effects"
const apiUrl = "https://jsonplaceholder.cypress.io/todos"
function getApi() {
return fetch(apiUrl, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json())
.catch(error => {
throw error
})
}
function* fetchTodos(action) {
try {
const todos = yield call(getApi)
const todosList = todos.slice(0, 20)
yield put({ type: "GET_TODOS", todosList })
} catch (error) {
console.log({ error })
}
}
function* todoSagas() {
yield takeEvery("GET_TODOS", fetchTodos)
}
export default todoSagas
解决方案
saga 本身正在创建一个无限循环,因为您使用相同的操作名称“GET_TODOS”来启动提取和存储提取结果。put
您的操作fetchTodos
将再次被您的takeEvery
.
您需要两种不同的操作类型,例如“REQUEST_TODOS”和“RECEIVE_TODOS”。请求操作没有有效负载,而成功操作有一个有效负载,其中包含来自您获取的待办事项数组。您的减速器会忽略请求操作(除非您想使用它来设置类似 的属性loading: true
)。对于成功操作,您的减速器将存储您从有效负载属性中获取的结果。
推荐阅读
- css - CSS:在某些选择器之前选择伪元素之后
- java - 在 JMeter 中发送肥皂消息中的动态值
- css - Vue + 顺风手风琴与过渡
- bootstrap-4 - 强制 justify-content-around 的最后一个元素与上一行的第一个元素对齐
- php - shopify如何删除应用程序卸载页面?
- java - TestNG beforeGroups 没有被执行
- python - 用于动态变量更改的 Jinja2 案例切换
- c - 需要帮助使用 qsort 从结构中对数组进行排序
- javascript - 通过选择 Div 属性更改 Div 的宽度
- sql - Oracle max(date) 显示不同的结果