放大 dynamodb graphql fetch 函数在循环中无限运行
Posted
技术标签:
【中文标题】放大 dynamodb graphql fetch 函数在循环中无限运行【英文标题】:amplify dynamodb graphql fetch function is running infinite in loop 【发布时间】:2021-06-27 02:56:17 【问题描述】:我正在尝试使用 graphql(AWS 放大 reacjs 设置)从 dynamodb 获取记录。我创建了一个组件 CTCards 并在 App.js 中使用它
我们面临的问题是函数 fetchTodos 在无限循环中运行,尽管在数据库中只有两条记录,而我得到的正好是 2 条记录,但是这个函数在无限循环中运行
当我注释获取代码时,程序会按预期运行
//== CTCards ( component which is giving issue) ===
function CTCards(props)
const [todo, setTodos] = useState([]);
useEffect(() =>
fetchTodos();
, []);
const fetchTodos = async () =>
try
// == this-block ===
const todoData = await API.graphql(graphqlOperation(listTodos));
const todoList = todoData.data.listTodos.items;
console.log('To Do List', todoList);
setTodos(todoList);
// == /this-block ===
catch (error)
console.log('error on fetching to do list', error);
;
return (
<div style=color: "red">
todo.map((todo, index) =>
<div style=color: "red">
<div>todo.name</div>
<div>todo.description</div>
</div>
)
</div>
)
//== App.js code ===
function App()
return (
<div>
<CTCards/>
</div>
);
【问题讨论】:
请在此处找到完整的代码库github.com/smaranneducations/react-amplified/blob/test/src/… 【参考方案1】:setTodos
正在重新安装组件,因此 useEffect
主体再次运行。
如果你注释掉setTodos
它应该可以正常运行。
您可以使用React.memo
来比较道具而不是虚拟 dom,但它仍然会进行无用的获取。考虑重组您的应用程序,以便提取发生在上一层。
【讨论】:
【参考方案2】:正如@arti91 所说,这是因为您正在更新状态,并且这样做会重新渲染组件并再次运行 useEffect 钩子。 如果您已经获取数据,一个可能的解决方案是检查钩子内部。
useEffect(() =>
if (!todos)
fetchTodos();
, []);
【讨论】:
如果我添加这个条件,那么 fetchTodos() 将不会被调用,因为 todos 在开始时是空的,因为 fetchTodos() 不会被调用状态不会改变,所以输出将为空白 我不确定我是否理解正确。您是说“if check”不正确并且“todos”为空时不调用 fetchTodos() 吗?在这种情况下尝试: if (todo.length === 0) fetchTodos() 【参考方案3】:代替这段代码:
try
// == this-block ===
const todoData = await API.graphql(graphqlOperation(listTodos));
const todoList = todoData.data.listTodos.items;
console.log('To Do List', todoList);
setTodos(todoList);
// == /this-block ===
catch (error)
console.log('error on fetching to do list', error);
试试这个代码:
try
const todoData = API.graphql( query: queries.listTodos ).then(response =>
setTodos(response.data.listTodos.items);
).catch(err =>
console.log(err);
);
catch (err)
console.log('error facing Todos:', err)
出现此问题是因为 Promise 仍处于预构建阶段,因此如果我们给它一些时间,它可以完成循环并获取值来存储它。
【讨论】:
await
等于 .then
- 只是更新的语法
在 map 下添加了一个 return 并且它起作用了,我错过了 todo.map((todo, index) => return ( todo.name todo.description ) ) 但为什么我们需要返回for map 因为它等于循环
你可以使用=> (
语法代替=> return (
以上是关于放大 dynamodb graphql fetch 函数在循环中无限运行的主要内容,如果未能解决你的问题,请参考以下文章
自动 DynamoDB 数据库检查 | ReactJS + AWS 放大
在 AWS Amplify GraphQL DynamoDB 中按另一个表的字段(也称为交叉表或嵌套过滤)过滤列表查询
调用graphql api时Flutter aws放大不返回数据