React Router 6 - 使用不同的路由路径将数据/状态从操作传递到加载器

问题描述 投票:0回答:1

我有一个包含帖子列表和帖子详细信息的应用程序。现在我正在尝试弄清楚如何在编辑帖子后有效地显示带有一些文本的吐司。

假设我有:

import { Form } from "react-router-dom"

<PostDetail>
    const navigation = useNavigation()

    const isSubmitting = navigation.formData?.get("title") != null

    <Form>
        <input type="text" name="title" />
        <button>
            {isSubmitting ? "Saving..." : "Save"}
        </button>
    </Form>
</PostDetail>

表单提交后,在 Action 函数上做一些事情(https://reactrouter.com/en/main/route/action),然后重定向到包含帖子列表的页面。

const postAction = async ({ request }: LoaderFunctionArgs) => {
    const formData = await request.formData()

    // call BE to update post and do some other stuff

    return redirect("/post/list")
}

之后,我想 在页面上显示一些带有帖子列表的 Toast 警报 f.e. (嘿,你的帖子已经更新了...)

我可以从操作

/post/:id
向加载程序
post/list
发送一些信息/状态吗?

react-router parameter-passing action toast loader
1个回答
0
投票

我尝试了一些解决方案。

1)

postAction()
中不返回
redirect()
,而是返回一些数据 (
{status: "post-updated"}
)。然后使用
useActionData()
钩子获取状态,通过
navigate('/post/list')

显示 toast 和来自组件的重定向力
<PostDetail>
    const actionData = useActionData()
    const navigate = useNavigate();
    const navigation = useNavigation()

    const isSubmitting = navigation.formData?.get("title") != null

    if (actionData?.status === "post-updated") {
       // show toast message
       navigate('/post/list')
    }

    ....
</PostDetail>

这个解决方案对我来说不好,因为我还使用

useNavigation()
钩子来检查“isSubmitting”状态并在提交按钮中显示不同的文本。当操作函数返回成功状态时,
useNavigation()
返回
state: "idle"
,而不是
state: "submitting"
。因此,在强制重定向之前,文本中出现了一些小故障(闪烁)。

2) 我的第二个解决方案是将搜索参数直接添加到操作函数中。组件中的 toast 消息强制执行,我在其中检查搜索参数。这是可行的,但我不喜欢周围混乱的代码。像useEffect一样添加useRef来防止渲染等

const postAction = async ({ request }: LoaderFunctionArgs) => {
    ....
    return redirect("/post/list?alert=edit")
}
const PostList = () => {
  const [searchParams, setSearchParams] = useSearchParams()

  const render = React.useRef(true)
  React.useEffect(() => {
    if (render.current) {
      render.current = false
      if (searchParams.has("alert")) {
        // show toast with message...
        searchParams.delete("alert")
        setSearchParams(searchParams, { replace: true })
      }
    }
  }, [])

}

所以我的问题是。还有其他解决方案吗,如何在操作和加载器之间传递一些数据?

谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.