Nextjs 和 TypeScript 中的条件渲染不起作用

Posted

技术标签:

【中文标题】Nextjs 和 TypeScript 中的条件渲染不起作用【英文标题】:Conditional Rendering in Nextjs & TypeScript not working 【发布时间】:2021-06-30 03:48:51 【问题描述】:

尝试有条件地渲染组件。我有一个 drawHelper 变量和一个函数来切换它的真假。组件渲染与否基于drawHelper 的initial 值。 (false,不渲染,true 会)。

切换功能更改值。我检查了 console.log(drawHelper) 但是更改值不会使组件出现或消失。

我错过了什么吗?

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import CssBaseline from '@material-ui/core/CssBaseline';
import Divider from '@material-ui/core/Divider';
import Drawer from '@material-ui/core/Drawer';
import Hidden from '@material-ui/core/Hidden';
import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import DashboardIcon from '@material-ui/icons/Dashboard';
import MenuIcon from '@material-ui/icons/Menu';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import  makeStyles, useTheme, Theme, createStyles  from '@material-ui/core/styles';
import  User  from './User';
import  Draw  from "components/Layout/Countryballs/Draw";
const drawerWidth = 240;

export const useStyles = makeStyles((theme: Theme) =>
  createStyles(
    root: 
      display: 'flex',
      color: '#fff',
    ,
    drawer: 
      [theme.breakpoints.up('sm')]: 
        width: drawerWidth,
        flexShrink: 0,
      ,
    ,
    appBar: 
      marginLeft: drawerWidth,
      [theme.breakpoints.up('sm')]: 
        width: `calc(100% - $drawerWidthpx)`,
      ,
    ,
    menuButton: 
      marginRight: theme.spacing(2),
      [theme.breakpoints.up('sm')]: 
        display: 'none',
      ,
    ,
    toolbar: theme.mixins.toolbar,
    drawerPaper: 
      width: drawerWidth,
      backgroundColor: theme.palette.primary.main
    ,
    content: 
      flexGrow: 1,
    ,
    menuItem: 
      color: '#fff',
    ,
  ),
);


export const Layout: React.FC<LayoutProps> = (props) => 
  const  container  = props;
  const classes = useStyles();
  const theme = useTheme();
  const [mobileOpen, setMobileOpen] = React.useState(false);

  function handleDrawerToggle() 
    setMobileOpen(!mobileOpen);
  



// Display Draw component
// 1 Create property

var drawHelper: Boolean = false;

  function toggleDraw() 
    console.log(drawHelper);
    drawHelper = !drawHelper;
  


  const drawer = (
    <div>
      <div className=classes.toolbar />
      <Divider />
      <List>

        ['Draw'].map((text) => (
          <ListItem button key=text onClick=toggleDraw className=classes.menuItem>
            <ListItemIcon className=classes.menuItem><DashboardIcon /></ListItemIcon>
            <ListItemText primary=text />
          </ListItem>
        ))
      </List>
    </div>
  );
  

  return (
    <div className=classes.root>
      <CssBaseline />
      <AppBar position="fixed" className=classes.appBar>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            edge="start"
            onClick=handleDrawerToggle
            className=classes.menuButton
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap>
            Project name
          </Typography>
          <User/>
        </Toolbar>
      </AppBar>
      <nav className=classes.drawer aria-label="mailbox folders">
        /* The implementation can be swapped with js to avoid SEO duplication of links. */
        <Hidden smUp implementation="css">
          <Drawer // this one is for mobile
            container=container
            variant="temporary"
            anchor=theme.direction === 'rtl' ? 'right' : 'left'
            open=mobileOpen
            onClose=handleDrawerToggle
            classes=
              paper: classes.drawerPaper,
            
            ModalProps=
              keepMounted: true, // Better open performance on mobile.
            
          >
            drawer
          </Drawer>
        </Hidden>
        
        <Hidden xsDown implementation="css">
          <Drawer // This one is for desktop
            classes=
              paper: classes.drawerPaper,
            
            variant="permanent"
            open
          >
            drawer
          </Drawer>
        </Hidden>
      </nav>
      <main className=classes.content>

/* This is where my components renders */

      
      drawHelper === true && (<Draw/>)
      


        
        <div className=classes.toolbar />
        props.children
      </main>
    </div>
  );

【问题讨论】:

【参考方案1】:

代码中的变量drawHelper 在每次渲染时都会被实例化。您可能希望使用 React 的状态来确保您的 drawHelper 的值在下一次重新渲染时得到保留。

const [drawHelper, toggleDrawHelper] = React.useState(false)


function toggleDraw() 
  toggleDrawHelper(!drawHelper);

【讨论】:

以上是关于Nextjs 和 TypeScript 中的条件渲染不起作用的主要内容,如果未能解决你的问题,请参考以下文章

暗模式在带有 Nextjs 和 Typescript 的 Tailwind CSS V3 中不起作用

TypeScript+NextJS 解构

NextJS _app.tsx Component 和 pageProps 应该是啥 TypeScript 类型?

NextJS/Typescript/Apollo 错误;类型上不存在属性

NextJS:处理 Connect / OwnProps / GetInitialProps 的最佳方式

如何允许 scss 开玩笑地对 typescript nextjs 进行单元测试?