【问题标题】:Media query syntax for ReactjsReactjs 的媒体查询语法
【发布时间】:2019-06-26 17:56:37
【问题描述】:

如何在 Reactjs 中进行以下 CSS 媒体查询?

.heading {
  text-align: right;
  /* media queries */
  @media (max-width: 767px) {
    text-align: center;
  }
  @media (max-width: 400px) {
    text-align: left;
  }
}

我尝试了以下方法,但它会引发语法错误并且无法编译。

heading: {
  textAlign: 'right',
  @media (maxWidth: '767px') {
    textAlign: 'center';
  }
  @media (maxWidth: '400px') {
    textAlign: 'left';
  }
}

【问题讨论】:

  • 你好,看我的回答。

标签: css reactjs media-queries jsx


【解决方案1】:

事实证明第二个答案非常有用,但是,它只是类组件中的示例,但是将其应用于功能组件通常很困难或很麻烦,而且由于有时将功能组件转换为有问题一类,这里我使用 Hooks

留下示例
import React, { useState, useEffect } from 'react';

const App = () => {
  const [matches, setMatches] = useState(
    window.matchMedia("(min-width: 768px)").matches
  )

  useEffect(() => {
    window
    .matchMedia("(min-width: 768px)")
    .addEventListener('change', e => setMatches( e.matches ));
  }, []);

  return (
    <div >
      {matches && (<h1>Big Screen</h1>)}
      {!matches && (<h3>Small Screen</h3>)}
    </div>
  );
}

export default App;

【讨论】:

  • 请注意addListenerdeprecated。建议使用addEventListener 代替:window.matchMedia('(min-width: 768px)').addEventListener('change', e =&gt; setMatches(e.matches))
【解决方案2】:

可以在 React 中进行媒体查询:

import React, { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props)
    this.state = { matches: window.matchMedia("(min-width: 768px)").matches };
  }

  componentDidMount() {
    const handler = e => this.setState({matches: e.matches});
    window.matchMedia("(min-width: 768px)").addEventListener('change', handler);
  }
  render() {
    return (
      <div >
      {this.state.matches && (<h1>Big Screen</h1>)}
      {!this.state.matches && (<h3>Small Screen</h3>)}
      </div>
    );
  }
}

export default App;

https://stackblitz.com/edit/react-cu8xqj?file=src/App.js


09-10-2021 编辑:将 addListener 替换为 addEventListener,因为前者是 deprecated。感谢 John Galt 通过发表评论告知我们。

【讨论】:

  • 你好@ferit,我说得对吗..我们必须创建不同的组件来处理大屏幕和小屏幕?所以我拥有的每个屏幕都需要为大屏幕和小屏幕创建?
  • 是的,我明白。我的问题是,为了解决不同的屏幕尺寸,我是否应该根据屏幕尺寸创建不同的视图和渲染?
  • @TommyLeong 那是响应式设计。您不能有 50 个屏幕,但可能最多需要 5 个不同的布局。无论 React 和这个答案如何,您都必须分别定义它们以获得响应式设计。
  • 请注意addListenerdeprecated。建议使用addEventListener 代替:window.matchMedia('(min-width: 768px)').addEventListener('change', e =&gt; e.matches)
  • 您可以通过消除handler 来进一步调整此功能,结果将是:window.matchMedia('(min-width: 768px)').addEventListener('change', (e) =&gt; this.setState({ matches: e.matches }))
【解决方案3】:

在reactjs项目中另一种编写媒体查询的方式:

style.js 文件:

root: {
 background: "white",

 "@media (max-width: 1920px)": {
   background: "red",
 }
}

style.css 文件:

.root: {
 background: "white";

 @media (max-width: 1920px) {
   background: "red";
 }
}

谢谢

【讨论】:

【解决方案4】:

aphrodite 可以帮忙。

这是example

import React from "react";
import { StyleSheet, css } from "aphrodite";

import "./style.css";

const styles = StyleSheet.create({
  heading: {
    textAlign: "right",
    backgroundColor: "red",
    "@media (max-width: 767px)": {
      textAlign: "center",
      backgroundColor: "green"
    },
    "@media (max-width: 767px)": {
      textAlign: "center",
      backgroundColor: "blue"
    }
  }
});

export default function App() {
  return (
    <div className={css(styles.heading)}>
      <h1>Hello aphrodite!</h1>
    </div>
  );
}

【讨论】:

    【解决方案5】:

    如果你习惯使用 css,你可以使用 styled-components。它看起来像这样。

    import React from 'react';
    import Styled from "styled-components";
    
    function YourComponent() {
    
        const heading = Styled.h1`
            Text-align:right;
    
                @media (max-width: 767px) {
                    text-align: center;
                }
                @media (max-width: 400px) {
                    text-align: left;
                }
        `;
    
       return(
            <>
               <heading>This is my heading</heading>
            </>
        )
    }
    

    如果你需要做很多样式,你可以在另一个 js 文件中做你的样式,并根据需要导入每个样式。如果您这样做,请不要忘记导出您的样式。

    【讨论】:

      【解决方案6】:

      您不能内联设置媒体查询。您需要创建一个单独的 CSS 样式表,然后导入该样式表。

      例如,以下代码将放入一个新的styles.css 文件中。

      .heading {
        text-align: right;
        /* media queries */
        @media (max-width: 767px) {
          text-align: center;
        }
        @media (max-width: 400px) {
          text-align: left;
        }
      }
      

      然后,您可以将新的 CSS 样式文件导入您的 react 文件。例如,您可以将 import './styles.css' 添加到您的 App.jsx 文件的顶部(假设它们都在根级别),或者您可以将其直接导入到特定的 react 组件文件中。

      【讨论】:

      • 你好,这不是真的,看我的回答。
      • 整洁。不错的更新。不过,没有必要否决我的答案。这是通过 web api,我的意思是你不能使用内联媒体查询。这仍然是正确的。
      • 你是对的,我的解决方案也不是内联的,所以没有办法进行内联查询。但是您也错了,因为您的回答意味着无法在 React 中进行媒体查询。这就是我投反对票的原因。
      • 谁说的里面有什么?不知道你说的里面是什么意思。这个问题没有具体说明“内部”。上面的方法是我在我的反应项目中使用媒体查询的方式。现在开始变得微不足道了。我认为您的评论是对答案的一个很好的补充,但是标记其他做同样事情的正确方法会适得其反。
      • 也许我认为它应该在里面。好的。请对您的答案进行细微的更改,以便我可以恢复我的反对票。
      【解决方案7】:

      在我的情况下,我使用自定义挂钩为我生成一些断点值:

      import { useMediaQuery } from 'react-responsive';
      
      export const useBreakpoints = () => {
        const isMobileSmall = useMediaQuery({ query: '(max-width: 325px)' });
        const isMobileMid = useMediaQuery({ query: '(max-width: 375px)' });
        const isMobileFloor = useMediaQuery({ query: '(max-width: 425px)' });
      
        const isTabletFloor = useMediaQuery({ query: '(max-width: 426px)' });
        const isTabletMid = useMediaQuery({ query: '(max-width: 768px)' });
        const isTabletCeil = useMediaQuery({ query: '(max-width: 1024px)' });
      
        const isLaptopFloor = useMediaQuery({ query: '(max-width: 1025px)' });
        const isLaptopCeil = useMediaQuery({ query: '(max-width: 1440px)' });
      
        const isXHDFloor = useMediaQuery({ query: '(max-width: 1441px)' });
        const isXHDCeil = useMediaQuery({ query: '(max-width: 4096px)' });
      
        return {
          isMobileSmall,
          isMobileMid,
          isMobileFloor,
          isTabletFloor,
          isTabletMid,
          isTabletCeil,
          isLaptopFloor,
          isLaptopCeil,
          isXHDFloor,
          isXHDCeil,
        };
      };
      
      

      我在 useMemo 内部的组件中调用它,这是不正确的 :)

      所以我把它放在useMemo 之外,它就像魅力一样!

      基本上我要指出的是避免使用嵌套的钩子调用!

      【讨论】:

        【解决方案8】:

        还有一种方法可以通过对 ex 使用布尔值来包含媒体查询。

        <div style={{window.innerWidth > 768 ? '800px' : '400px'}}/>
        

        这很好地解决了问题

        【讨论】:

        • 那不会使其响应。只有在刷新之后。
        【解决方案9】:

        如果你有特殊情况,当你需要在你的 react 应用程序中获取媒体查询结果时(例如,你想在移动版本中显示一些组件),你可以使用像 react-responsivereact-media-hook 这样的 helpers。

        【讨论】:

          猜你喜欢
          • 2022-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          相关资源
          最近更新 更多