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
};
在进入解决方案之前,您需要记住两件事:
- 基于 State 或 Prop 变化的组件 re-renders,就是这样。
- 您必须使用
localStorage
之类的东西在浏览器中保存您的登录信息,这样无论重新加载您的页面,您都知道用户是否已登录。
所以回来了,你必须根据登录信息(可以是任何东西,但最有可能是用户信息 and/or access/auth 令牌)有条件地呈现 link将在登录后本地保存在浏览器存储中。但是有一个问题,从 localStorage
保存和取回登录数据是不够的,因为我们需要状态或道具形式的数据,因为只有这样组件才会对变化做出反应。因此,为了解决这个问题,您将不得不以某种方式将 localStorage
中的数据与 state/prop.
中的数据同步
要实现这一点,可以结合使用 redux
、react-redux
和 redux-persist
来解决这个问题。所以基本上它的工作方式与普通 redux 流程的工作方式相同,但主要更改将通过 redux-persist
保留您的登录信息来完成。一旦你用redux-persist
包装你的登录reducer,它会自动persist/sync你的登录reducer localStorge
。你可能会找到很多这样的例子。因此,您将在收到响应并将相关数据作为其参数(将保存在商店中)后发送您的登录操作,其余的将由 redux
处理。之后,您只需要从 header 中的 redux
获取您的登录状态,并基于此有条件地呈现您的 link.
这是一种可能的解决方案,但无论如何您都知道它是如何工作的。如果你愿意,你可以使用 Context
而不是 Redux
,但无论如何你明白了。
在这种情况下,当用户登录时,他将被重定向到消息页面。我希望 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
};
在进入解决方案之前,您需要记住两件事:
- 基于 State 或 Prop 变化的组件 re-renders,就是这样。
- 您必须使用
localStorage
之类的东西在浏览器中保存您的登录信息,这样无论重新加载您的页面,您都知道用户是否已登录。
所以回来了,你必须根据登录信息(可以是任何东西,但最有可能是用户信息 and/or access/auth 令牌)有条件地呈现 link将在登录后本地保存在浏览器存储中。但是有一个问题,从 localStorage
保存和取回登录数据是不够的,因为我们需要状态或道具形式的数据,因为只有这样组件才会对变化做出反应。因此,为了解决这个问题,您将不得不以某种方式将 localStorage
中的数据与 state/prop.
要实现这一点,可以结合使用 redux
、react-redux
和 redux-persist
来解决这个问题。所以基本上它的工作方式与普通 redux 流程的工作方式相同,但主要更改将通过 redux-persist
保留您的登录信息来完成。一旦你用redux-persist
包装你的登录reducer,它会自动persist/sync你的登录reducer localStorge
。你可能会找到很多这样的例子。因此,您将在收到响应并将相关数据作为其参数(将保存在商店中)后发送您的登录操作,其余的将由 redux
处理。之后,您只需要从 header 中的 redux
获取您的登录状态,并基于此有条件地呈现您的 link.
这是一种可能的解决方案,但无论如何您都知道它是如何工作的。如果你愿意,你可以使用 Context
而不是 Redux
,但无论如何你明白了。