0

我在尝试使用 reactDomServer 和静态路由器进行服务器端渲染时遇到错误。

我得到以下输出:

Error: Invariant failed: You should not use <Switch> outside a <Router>
at invariant (webpack:///./node_modules/tiny-invariant/dist/tiny-invariant.esm.js?:14:9)
at Object.eval [as children] (webpack:///./node_modules/react-router/esm/react-router.js?:658:88)
at ReactDOMServerRenderer.render (/home/jesusap21/jps_webapp/node_modules/react-dom/cjs/react-dom-server.node.development.js:3635:55)
at ReactDOMServerRenderer.read (/home/jesusap21/jps_webapp/node_modules/react-dom/cjs/react-dom-server.node.development.js:3373:29)
at Object.renderToString (/home/jesusap21/jps_webapp/node_modules/react-dom/cjs/react-dom-server.node.development.js:3988:27)
at Server.<anonymous> (/home/jesusap21/jps_webapp/src/ssr/http.js:23:37)
at Server.emit (events.js:198:13)
at parserOnIncoming (_http_server.js:691:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:17)

我的服务器:

http.createServer((req, res) => {
    // This context object contains the results of the render
    const context = {};
    const html = ReactDOMServer.renderToString(
        <ReactRouter.StaticRouter location={req.url} context={context}>
            <App />
        </ReactRouter.StaticRouter>
    );

    // context.url will contain the URL to redirect to if a <Redirect> was used
    if (context.url) {
        res.writeHead(302, {
            Location: context.url
        });
    } else {
        res.write(html);
    }
    res.end();
}).listen(port);

我在客户端使用 BrowserRouter,并且使用相同的组件“App”可以正常工作。但在服务器端我遇到了这个问题。

** 编辑 **

这是我的应用程序组件代码:

import React from 'react';
import configureStore from './store/configureStore';
import { Provider } from 'react-redux';
import Container from './Container'

const store = configureStore();

export default class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                <Container />
            </Provider>
        )
    }
}

然后是我的容器

 function Container(props: LinkStateProp) {
  const theme = createMuiTheme({
    palette: {
      primary: {
        light: 'rgba(153, 28, 31, 0.4)',
        main: '#C8283B',
        contrastText: '#FFFFFF',
      },
      secondary: {
        light: '#F2F2F2',
        main: 'rgba(0, 0, 0, 0.08)',
        dark: 'rgba(0, 0, 0, 0.2)',
        contrastText: '#000000',
      },
      contrastThreshold: 3,
      tonalOffset: 0.2,
    },
    typography: {
      fontFamily: "Roboto",
    }
  });

  const useStyles = makeStyles((theme: Theme) =>
    createStyles({
      root: {

      },
      layout: {
        marginTop: '10vh',
        minHeight: '90vh',
        display: 'flex',
      }
    }),
  );

  const classes = useStyles();
  const [open, setOpen] = React.useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (    
      <Switch>
        <MuiThemeProvider theme={theme}>
          <Container className={classes.root} maxWidth={false} disableGutters={true}>
            <Nav open={open} handleDrawerOpen={handleDrawerOpen} handleDrawerClose={handleDrawerClose}/>
            <LeftDrawer open={open} handleDrawerClose={handleDrawerClose}/>
              <div className={classes.layout}>
                <Route exact path="/" component={Home}/>
                <Route exact path="/iniciarsesion">
                  {props.isAuthUser ? <Redirect to="/" /> : <SignIn />}
                </Route>
                <Route exact path="/crearcuenta">
                  {props.isAuthUser ? <Redirect to="/" /> : <SignUp />}
                </Route>
              </div>
          </Container>
        </MuiThemeProvider>
      </Switch>
  );
}


interface LinkStateProp {
  isAuthUser: boolean,
}

const mapStateToProps = (state: ApplicationState) => ({
  isAuthUser: state.customer.isAuthUser,
});

export default connect(mapStateToProps)(Container);
4

1 回答 1

0

您需要<Router><Provider/>在 App Component中使用一样包装容器

            <Provider store={store}>
              <Router>
                <Container />
             </Router>
            </Provider>
于 2020-06-01T03:19:06.837 回答