![](/img/trans.png)
[英]How to get jwt token from url in react using react-router-dom v6
[英]react-router-dom v6 StaticRouter context is not working
我正在尝试制作 SSR React web 应用程序。 除了 staticContext 之外,一切正常。
我的服务器代码是
// IMPORTS
const renderer = (req, store, context) => {
const content = renderToString(
<Provider store={store}>
<ThemeProvider theme={responsiveFontSizes(theme)}>
<CssBaseline />
<StaticRouter location={req.path} context={context}>
<Navigation />
<main>
{renderRoutes(MainRouter)}
</main>
<Footer />
</StaticRouter>
</ThemeProvider>
</Provider>
);
const helmet = Helmet.renderStatic();
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="icon" href="${process.env.REACT_APP_URL}/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="${process.env.REACT_APP_THEME_COLOR}" />
${helmet.title.toString()}
${helmet.meta.toString()}
<link rel="stylesheet" href="main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
</head>
<body>
<noscript>Pre dokonalé fungovanie tejto webovej aplikácie povoľte JavaScript.</noscript>
<div id="root">${content}</div>
<script>
window.INITIAL_STATE = ${serialize(store.getState())}
</script>
<script src="bundle.js"></script>
</body>
</html>
`;
};
app.get('*', (req, res) => {
const store = createStore();
var promises = matchRoutes(MainRouter, req.path).map(route => {
return route?.loadData ? route.loadData(store) : [];
});
promises.push(loadData(store, req.cookies));
Promise.all(promises).then(() => {
const context = {};
const content = renderer(req, store, context);
if(context.url) {
return res.redirect(302, context.url);
}
if(context.notFound) {
console.log('404');
res.status(404);
};
res.send(content);
});
});
我的 404 组件的客户端代码是
const NotFound = ({ staticContext = {} }) => {
staticContext.notFound = true;
const head = () => (
<Helmet>
<title>{process.env.REACT_APP_NAME} – Stránka sa nenašla</title>
</Helmet>
);
return (
<React.Fragment>
{head()}
<section>
{/* Some content */}
</section>
</React.Fragment>
)
};
export default {
Component: NotFound
};
此行应将notFound = true参数传递到请求中:
staticContext.notFound = true;
因此,这部分代码应将请求状态设置为 404 并将控制台日志设置为“404”字符串:
if(context.notFound) {
console.log('404');
res.status(404);
};
但它不起作用。 我的代码是否有可能被弃用? 我正在使用所有依赖项的当前最新稳定版本。
我的 package.json 依赖项
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@mui/icons-material": "^5.2.5",
"@mui/material": "^5.2.5",
"axios": "0.24.0",
"babel-cli": "6.26.0",
"babel-core": "6.26.3",
"babel-loader": "8.2.3",
"compression": "1.7.4",
"concurrently": "6.5.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"date-fns": "^2.27.0",
"express": "4.17.2",
"lodash": "4.17.21",
"nodemon": "2.0.15",
"npm-run-all": "4.1.5",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-helmet": "6.1.0",
"react-redux": "^7.2.6",
"react-router-dom": "6.2.1",
"react-spinners": "^0.11.0",
"redux": "^4.1.2",
"serialize-javascript": "6.0.0",
"universal-cookie": "^4.0.4",
"webpack": "5.65.0",
"webpack-dev-server": "4.7.1",
"webpack-merge": "5.8.0",
"webpack-node-externals": "3.0.0"
我在使用 SSR 的 StaticRouter 时遇到了一个一般的导入错误,并从 Google 登陆了这个页面(粘贴错误时)。 如果其他人有类似的问题,似乎在react-router-dom
v6 中, StaticRouter
现在应该从react-router-dom/server
导入。
我也有同样的问题,请问你解决了吗?
我的代码有可能被弃用吗?
恐怕是。
这是v6.0.0-alpha.4的主要变化之一:
删除了
<StaticRouter context>
API。 我们在 v6 中不支持在初始渲染上导航,所以这个 API 是不必要的。
我最终将状态代码存储在 Redux 存储中,并在NotFound
页面组件的loadData
function 中调度setStatus(404)
操作。 但我不确定这是否可以应用于您的案例,存储重定向 URL。
想到的另一种方法是使用 React 上下文并将上下文值(您传递给您的renderer
)提供给NotFound
页面组件。
从 v6 开始, <StaticRouter context>
将不再可用。 但是,这很容易修复。 您应该改用React Context 。
首先,您必须创建StaticContext.js
文件:
import { createContext, useContext } from 'react';
const StaticContext = createContext({});
const StaticProvider = ({ children, value }) => (
<StaticContext.Provider value={value}>
{children}
</StaticContext.Provider>
);
const useStaticContext = () => useContext(StaticContext);
export { StaticProvider, useStaticContext };
默认情况下,该文件将设置空上下文数据 ( {}
)。 然后,您应该在服务器渲染中使用StaticContext.Provider
在应用程序之间共享它:
import { StaticProvider } from './contexts/StaticContext';
// ...
const context = {};
const content = renderToString(
<Provider store={store}>
<ThemeProvider theme={responsiveFontSizes(theme)}>
<CssBaseline />
<StaticRouter location={req.path}>
<StaticProvider value={context}>
<Navigation />
<main>
{renderRoutes(MainRouter)}
</main>
</StaticProvider>
<Footer />
</StaticRouter>
</ThemeProvider>
</Provider>
);
首先,您必须设置上下文 object 并将其传递给 StaticProvider 元素。 然后将您的应用程序包装到它上面。 稍后,您应该使用useStaticContext
function 从上下文中获取和操作数据:
import { useStaticContext } from '../contexts/StaticContext';
import 'react';
export default function NotFoundPage() {
const context = useStaticContext();
context.notFound = true;
}
最后一件事,您可以使用context.notFound
访问服务器上的上下文变量。
您可以使用 ThemeProvider 来处理未找到的页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.