如何在类组件中使用 useMediaQuery

IT技术 javascript reactjs material-ui react-hooks
2021-05-08 10:23:03

将函数用作组件时,您可以使用useMediaQuerymaterial-ui 中钩子。然而,它没有告诉你如何在类中使用这个钩子。

所以我做了一些研究,发现你可以通过这样做在课堂上使用它:

import React from 'react';
import useMediaQuery from '@material-ui/core/useMediaQuery';

const withMediaQuery = (...args) => Component => props => {
  const mediaQuery = useMediaQuery(...args);
  return <Component mediaQuery={mediaQuery} {...props} />;
};

export default withMediaQuery;

但是,当像这样将它添加到类时:

export default withStyles(styles)(withMediaQuery(Main));

它给了我这个错误:

index.js:1 Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

我真的需要使用媒体查询,因为有些变量依赖于它们。这是我想使用媒体查询的类的渲染方法。

render() {

    const { classes, children } = this.props;

    const isDesktop = useMediaQuery(theme => theme.breakpoints.up('lg'), {
      defaultMatches: true,
    });

    const shouldOpenSidebar = isDesktop ? true : this.state.openSidebar;

    return (
      <div
        className={cc({
          [classes.root]: true,
          [classes.shiftContent]: isDesktop,
        })}>
        <Topbar
          onSidebarOpen={this.handleSidebarOpen}
        />
        <Sidebar
          onClose={this.handleSidebarClose}
          open={shouldOpenSidebar}
          variant={isDesktop ? 'persistent' : 'temporary'}
        />
        <main className={classes.content}>
          {children}
        </main>
      </div>
    );
  }

我已经尝试过包装组件,但是我将无法使用这些变量

2个回答

您没有提供args所需的useMediaQuery,因此Main作为 传递args,并返回一个期望该组件的函数。当 React 尝试渲染(调用函数)时,返回值是另一个函数,它不是作为 React 子对象的值。

调用函数 -withMediaQuery并将媒体查询传递Main它,然后传递给返回的函数。

例子:

export default withStyles(styles)(withMediaQuery('(min-width:600px)')(Main));

与其将自己限制在一个媒体查询中,不如使用 MediaQuery HOC

import React from 'react'
import useMediaQuery from '@material-ui/core/useMediaQuery'

export const withMediaQuery = (queries = []) => Component => props => {
  const mediaProps = {}
  queries.forEach(q => {
    mediaProps[q[0]] = useMediaQuery(q[1])
  })
  return <Component {...mediaProps} {...props} />
}

这将允许您将多个查询作为数组数组传递。每个条目将是一个props名称,然后是查询。

export default withStyles(styles)(withMediaQuery([
    ['isDesktop', theme => theme.breakpoints.up('lg'), {
      defaultMatches: true
    }]
  ]))

在您的组件中,您可以直接在渲染中请求props名称

render() {

    const { classes, children, IsDesktop = false } = this.props;

    const shouldOpenSidebar = IsDesktop ? true : this.state.openSidebar;

    return (
      <div
        className={cc({
          [classes.root]: true,
          [classes.shiftContent]: isDesktop,
        })}>
        <Topbar
          onSidebarOpen={this.handleSidebarOpen}
        />
        <Sidebar
          onClose={this.handleSidebarClose}
          open={shouldOpenSidebar}
          variant={isDesktop ? 'persistent' : 'temporary'}
        />
        <main className={classes.content}>
          {children}
        </main>
      </div>
    );
  }