Reactjs 的媒体查询语法

IT技术 css reactjs media-queries jsx
2021-03-26 18:51:42

如何在 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';
  }
}
6个回答

可以在 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


2021年9月10日编辑:更换addListeneraddEventListener作为前者被弃用感谢 John Galt 通过发表评论让我们知道。

只是一个addListener弃用的提示建议addEventListener改用:window.matchMedia('(min-width: 768px)').addEventListener('change', e => e.matches)
2021-05-29 18:51:42
是的我明白。我的问题是,为了解决不同的屏幕尺寸,我是否应该根据屏幕尺寸创建不同的视图和渲染?
2021-05-31 18:51:42
你好@ferit,我说的对吗..我们必须创建不同的组件来处理大屏幕和小屏幕?那么我拥有的每个屏幕都需要为大小创建吗?
2021-06-03 18:51:42
您可以通过消除 来进一步修剪此函数handler,结果将是:window.matchMedia('(min-width: 768px)').addEventListener('change', (e) => this.setState({ matches: e.matches }))
2021-06-19 18:51:42
@TommyLeong 那是响应式设计。您不能有 50 个屏幕,但最多可能需要 5 种不同的布局。无论 React 和这个答案如何,您都必须分别定义它们中的每一个以获得响应式设计。
2021-06-20 18:51:42

您不能内联设置媒体查询。您需要创建一个单独的 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 组件文件中。

也许我认为它应该在里面。行。请对您的答案进行微不足道的更改,以便我可以恢复我的反对票。
2021-05-22 18:51:42
整洁的。不错的更新。不过,没有必要对我的答案投反对票。这是通过 web api,我的意思是你不能使用内联媒体查询。这仍然是真的。
2021-05-24 18:51:42
您好,这不是真的,请参阅我的回答。
2021-05-28 18:51:42
你是对的,我的解决方案也不是内联的,所以无法进行内联查询。但是您也错了,因为您的回答暗示无法在 React 中进行媒体查询。这就是我投反对票的原因。
2021-06-07 18:51:42
谁说里面的?我不确定你说的里面是什么意思。这个问题没有具体说明“内部”的任何内容。上面的方法是我在 React 项目中使用媒体查询的方式。这现在开始变得小气了。我认为你的评论是对答案的一个很好的补充,但标记做同样事情的其他正确方法会适得其反。
2021-06-18 18:51:42

如果您有特殊情况,当您需要在 React 应用程序中获取媒体查询结果时(例如,您想在移动版本中显示某个组件),您可以使用诸如react-responsivereact-media-hook 之类的助手

如果您习惯使用 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 文件中做你的样式并根据需要导入每个样式。如果您这样做,请不要忘记导出您的样式。

事实证明第二个答案非常有用,但是,它只是类组件中的示例,但是将其应用于功能组件通常很困难或很麻烦,因为有时将功能组件转换为类组件是有问题的, 在这里我使用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;
只是一个addListener弃用的提示建议addEventListener改用:window.matchMedia('(min-width: 768px)').addEventListener('change', e => setMatches(e.matches))
2021-06-01 18:51:42