Reactjs 的媒体查询语法
Posted
技术标签:
【中文标题】Reactjs 的媒体查询语法【英文标题】:Media query syntax for Reactjs 【发布时间】: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';
【问题讨论】:
你好,看我的回答。 【参考方案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;
【讨论】:
请注意addListener
是deprecated。建议使用addEventListener
代替:window.matchMedia('(min-width: 768px)').addEventListener('change', e => 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 和这个答案如何,您都必须分别定义它们以获得响应式设计。 请注意addListener
是deprecated。建议使用addEventListener
代替:window.matchMedia('(min-width: 768px)').addEventListener('change', e => e.matches)
。
您可以通过消除handler
来进一步调整此功能,结果将是:window.matchMedia('(min-width: 768px)').addEventListener('change', (e) => 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";
谢谢
【讨论】:
如果使用材质 UI 试试这个:material-ui.com/customization/breakpoints【参考方案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-responsive 或 react-media-hook 这样的 helpers。
【讨论】:
以上是关于Reactjs 的媒体查询语法的主要内容,如果未能解决你的问题,请参考以下文章