【问题标题】:How do I conditionally render CSS with Material UI useStyles/makeStyles?如何使用 Material UI useStyles/makeStyles 有条件地渲染 CSS?
【发布时间】:2022-01-09 12:40:16
【问题描述】:

如果道具满足特定条件,我正在尝试将 latestMessageText 变量显示为粗体和黑色。 useEffect 方法有效,一个丑陋的解决方案;如何使用 Material UI 的 useStyle 挂钩来执行我的目标。我尝试将道具传递给 useStyle,在 makeStyles 函数中使用它们,但没有效果。

import React, { useEffect, useRef } from "react";
import { Box, Typography } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
  root: {
    display: "flex",
    justifyContent: "space-between",
    marginLeft: 20,
    flexGrow: 1,
  },
  username: {
    fontWeight: "bold",
    letterSpacing: -0.2,
  },
  previewText: {
    fontSize: 12,
    // color: "#9CADC8",
    letterSpacing: -0.17,
    color: (messages, otherUser) => {
      if (messages.length && otherUser) {
        const lastMessage = messages[messages.length - 1];
        const { senderId, receiverHasRead } = lastMessage;
        if (senderId === otherUser.id && !receiverHasRead) {
          return 'black'
        }
        return "#9CADC8"
      }
    }
  },
  black: {
    color: 'black',
    fontWeight: 700,
  }
}));

const ChatContent = (props) => {
  const { conversation } = props;
  const { latestMessageText, otherUser, messages } = conversation;
  const classes = useStyles(messages, otherUser);

  return (
    <Box className={classes.root}>
      <Box>
        <Typography className={classes.username}>
          {otherUser.username}
        </Typography>
        <Typography className={classes.previewText}>
          {latestMessageText}
        </Typography>
      </Box>
    </Box>
  );
};

export default ChatContent;

【问题讨论】:

    标签: javascript css reactjs material-ui


    【解决方案1】:

    我在这里推荐使用 一个小的 (228B) 实用程序来有条件地构造 className 字符串,即 clsx

    我在这里提供了解决方案。

    第一种方法使用{[yourclass]: conditon}语法:

    import React, { useEffect, useRef } from "react";
    import { Box, Typography } from "@material-ui/core";
    import { makeStyles } from "@material-ui/core/styles";
    import clsx from 'clsx';
    
    const useStyles = makeStyles((theme) => ({
      root: {
        display: "flex",
        justifyContent: "space-between",
        marginLeft: 20,
        flexGrow: 1,
      },
      username: {
        fontWeight: "bold",
        letterSpacing: -0.2,
      },
      previewText: {
        fontSize: 12,
        color: "#9CADC8",
        letterSpacing: -0.17,
      },
      black: {
        color: 'black',
        fontWeight: 700,
      }
    }));
    
    const ChatContent = (props) => {
      const classes = useStyles();
      const typeographyEl = useRef();
    
      const { conversation } = props;
      const { latestMessageText, otherUser, messages } = conversation;
    
      const lastMessage = messages?.length && messages[messages.length - 1];
      const { senderId, receiverHasRead } = lastMessage;
    
      return (
        <Box className={classes.root}>
          <Box>
            <Typography className={classes.username}>
              {otherUser.username}
            </Typography>
            <Typography ref={typeographyEl} className={clsx(classes.previewText, {[classes.black]: senderId === otherUser.id && !receiverHasRead})}>
              {latestMessageText}
            </Typography>
          </Box>
        </Box>
      );
    };
    
    export default ChatContent;
    

    第二种方法使用{conditon &amp;&amp; yourstyle}语法:

     <Typography ref={typeographyEl} 
                 className={clsx(classes.previewText, {(senderId === otherUser.id && !receiverHasRead) && classes.black})}>
              {latestMessageText}
     </Typography>
    

    【讨论】:

    • 它有效。谢谢!
    【解决方案2】:

    这不是 React 处理这类函数的方式。您需要在状态变量(如果您希望它通过用户交互更改)或常量变量中获取条件,并基于此设置类。

    const [messageRead, setMessageRead] = useState(false);
    useEffect(() => {
      if (messages.length) {
        const { senderId, receiverHasRead } = messages[messages.length - 1];
        setMessageRead(senderId === otherUser.id && !receiverHasRead);
      }
    }, [messages, otherUser]);
    

    JSX

    <Typography className={`${classes.previewText} ${messageRead ? classes.black : ''}`}>
      {latestMessageText}
    </Typography>
    

    您可以使用classnamesclsx npm 包来简化三元条件。

    【讨论】:

      猜你喜欢
      • 2020-04-01
      • 2020-08-16
      • 2021-12-06
      • 2022-01-06
      • 2021-01-30
      • 1970-01-01
      • 2020-01-27
      • 2012-06-16
      • 2020-07-15
      相关资源
      最近更新 更多