Re-render 使用 navigate('/path') 后的一个组件

Re-render a component after using navigate('/path')

在这种情况下,当用户登录时,他将被重定向到消息页面。我希望 header 组件在此之后呈现,但它没有发生。如果 header 被渲染,一个 link 会改变,但如果不渲染, link 将保持不变,直到页面刷新...... 我能做什么?!

login.js:

const login = async (e) => {
    e.preventDefault();
    const result = await (
      await fetch("/portfolio/login", {
        method: "POST",
        credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
      })
    ).json();
    if (result.accessToken) {
      navigate("/message");    //imported from @reach/router
    } else console.log(result.error);
    if (result.message) setRes(result.message);
  };

header.js:

const Header = () => {
  const [tokenObj, setToken] = useState('');
  
  useEffect(() => {
    fetch('/portfolio/verify', {method : "GET"})
    .then((res)=>{
      if(res.ok) return res.json(res);
    })
    .then((jsonRes)=> {
      if(jsonRes.token) setToken(jsonRes.token)
    });
  }, [tokenObj]);

  let lastNavLink;
  let lastNavHref;
  if(tokenObj){ 
    lastNavLink = 'Messages';
    lastNavHref = '/message'
  } else {
    lastNavLink = 'Login';
    lastNavHref = '/login';
  }
    return <a href={lastNavHref}> {lastNavLink} </a> //dynamic link
};

在进入解决方案之前,您需要记住两件事:

  1. 基于 State 或 Prop 变化的组件 re-renders,就是这样。
  2. 您必须使用 localStorage 之类的东西在浏览器中保存您的登录信息,这样无论重新加载您的页面,您都知道用户是否已登录。

所以回来了,你必须根据登录信息(可以是任何东西,但最有可能是用户信息 and/or access/auth 令牌)有条件地呈现 link将在登录后本地保存在浏览器存储中。但是有一个问题,从 localStorage 保存和取回登录数据是不够的,因为我们需要状态或道具形式的数据,因为只有这样组件才会对变化做出反应。因此,为了解决这个问题,您将不得不以某种方式将 localStorage 中的数据与 state/prop.

中的数据同步

要实现这一点,可以结合使用 reduxreact-reduxredux-persist 来解决这个问题。所以基本上它的工作方式与普通 redux 流程的工作方式相同,但主要更改将通过 redux-persist 保留您的登录信息来完成。一旦你用redux-persist包装你的登录reducer,它会自动persist/sync你的登录reducer localStorge。你可能会找到很多这样的例子。因此,您将在收到响应并将相关数据作为其参数(将保存在商店中)后发送您的登录操作,其余的将由 redux 处理。之后,您只需要从 header 中的 redux 获取您的登录状态,并基于此有条件地呈现您的 link.

这是一种可能的解决方案,但无论如何您都知道它是如何工作的。如果你愿意,你可以使用 Context 而不是 Redux,但无论如何你明白了。