访问 aws amplify 订阅中的最新状态值反应

Posted

技术标签:

【中文标题】访问 aws amplify 订阅中的最新状态值反应【英文标题】:Access latest value of state in aws amplify subscriptions react 【发布时间】:2021-11-15 23:55:55 【问题描述】:

我有一个使用 aws-amplify 的订阅监听器的 useEffect 钩子。

useEffect(() => 
        todoUpdatedSubs.subscribe(
          next: (status: SubscriptionStatus<OnTodoUpdatedSubscription>) => 
            setIsTaskUpdated(true);
            // when mutation will run the next will trigger
            console.log("New Updated SUBSCRIPTION ==> ", status);
            if (!status.value.data.onTodoUpdated.success)
              return console.log("error", status);
    
            const newArr = [...todos];
            console.log("Prev todos", todos);
            const  id, todo, isCompleted  = status.value.data.onTodoUpdated;
            newArr[editingIndex] =  id, todo, isCompleted ;
            setTodos(newArr);
          ,
        );, [])

问题在于 useEffect 中的 next 函数没有todo state 的最新值,因为 useEffect 仅在 mount 时运行。如果我这样做,则会安装多个侦听器:

useEffect(() => 
        todoUpdatedSubs.subscribe(
          next: (status: SubscriptionStatus<OnTodoUpdatedSubscription>) => 
            setIsTaskUpdated(true);
            // when mutation will run the next will trigger
            console.log("New Updated SUBSCRIPTION ==> ", status);
            if (!status.value.data.onTodoUpdated.success)
              return console.log("error", status);
    
            const newArr = [...todos];
            console.log("Prev todos", todos);
            const  id, todo, isCompleted  = status.value.data.onTodoUpdated;
            newArr[editingIndex] =  id, todo, isCompleted ;
            setTodos(newArr);
          ,
        );, [todos])

如何获取监听器中的最新状态值?

【问题讨论】:

【参考方案1】:

使用useState 挂钩的functional updates 选项。使用回调设置状态时,将使用以前的值调用回调。这使您无需将todos 定义为useEffect 的依赖项。

useEffect(() => 
  todoUpdatedSubs.subscribe(
    next: (status: SubscriptionStatus<OnTodoUpdatedSubscription>) => 
      setIsTaskUpdated(true);
      // when mutation will run the next will trigger
      console.log("New Updated SUBSCRIPTION ==> ", status);
      if (!status.value.data.onTodoUpdated.success)
        return console.log("error", status);
        
      setTodos(todos => 
        const newArr = [...todos];
        const  id, todo, isCompleted  = status.value.data.onTodoUpdated;
        newArr[editingIndex] =  id, todo, isCompleted ;
        
        return newArr;
      );
    ,
);, [])

如果您需要在useEffect 中使用更新后的todos 值,但在更新状态时不需要,则可以使用useRef

在您的情况下,我将使用功能更新选项,但我将其添加为示例:

const todosRef = useRef();

useEffect(() => 
  todosRef.current = todos;
);

useEffect(() => 
  todoUpdatedSubs.subscribe(
    next: (status: SubscriptionStatus<OnTodoUpdatedSubscription>) => 
      setIsTaskUpdated(true);
      // when mutation will run the next will trigger
      console.log("New Updated SUBSCRIPTION ==> ", status);
      if (!status.value.data.onTodoUpdated.success)
        return console.log("error", status);
        
      const newArr = [...todosRef.current];
      const  id, todo, isCompleted  = status.value.data.onTodoUpdated;
      newArr[editingIndex] =  id, todo, isCompleted ;
      setTodos(newArr);
    ,
);, [])

【讨论】:

好的,让我检查一下。 我不知道为什么但是这个方法没有重新渲染列表 在相关的useState()之后添加console.log(todos)到组件的主体(不在useEffect()内)。 我尝试了一种不同的方法,基本上,我设置了一个新的状态来保存更新的 todo 值和一个使用该状态作为修改 todo 列表的 dep 的 useEffect。你能告诉我这是否是正确的方法吗? 不。正确的做法是设置状态的回调。我添加了另一种使用 ref 的方法。使用另一个状态是多余的。但是,如果它对您有用...

以上是关于访问 aws amplify 订阅中的最新状态值反应的主要内容,如果未能解决你的问题,请参考以下文章

AWS Amplify AppSync 订阅:数据返回 null

AWS Amplify AppSync 订阅无法正常工作

如何使用 Amplify 框架从 AWS 中的 API 获取 http 状态和详细响应?

AWS Amplify Cognito 中的禁用用户仍然可以访问 API 中的数据

更新AWS Amplify中现有应用程序的回购访问密钥

AWS Amplify,如何检查用户是不是登录?