Как переопределить классы, используя makeStyles и useStyles в material-ui? - PullRequest
1 голос
/ 01 мая 2020

Рассмотрим компонент, который отображает кнопку и говорит, что эта кнопка должна иметь красный фон и желтый цвет текста. Также существует родительский компонент, который использует этот дочерний элемент, но говорит, что желтый цвет в порядке, но я хочу, чтобы цвет фона был зеленым.

withStyles

Нет проблем с использованием старого withStyles.

import React from "react";
import { withStyles } from "@material-ui/core/styles";
import { Button } from "@material-ui/core";

const parentStyles = {
  root: {
    background: "green"
  }
};
const childStyles = {
  root: {
    background: "red"
  },
  label: {
    color: "yellow"
  }
};

const ChildWithStyles = withStyles(childStyles)(({ classes }) => {
  return <Button classes={classes}>Button in Child withStyles</Button>;
});

const ParentWithStyles = withStyles(parentStyles)(({ classes }) => {
  return <ChildWithStyles classes={classes} />;
});


export default ParentWithStyles;

Button in child using withStyles

https://codesandbox.io/s/passing-classes-using-withstyles-w17xs?file= / demo.tsx

makeStyles / useStyles

Давайте вместо этого попробуем makeStyles / useStyles и следуем руководству Переопределение стилей - классы prop на material-ui.com.

import React from "react";
import { makeStyles } from "@material-ui/styles";
import { Button } from "@material-ui/core";

const parentStyles = {
  root: {
    background: "green"
  }
};
const childStyles = {
  root: {
    background: "red"
  },
  label: {
    color: "yellow"
  }
};

// useStyles variant does NOT let me override classes
const useParentStyles = makeStyles(parentStyles);
const useChildStyles = makeStyles(childStyles);

const ChildUseStyles = ({ classes: classesOverride }) => {
  const classes = useChildStyles({ classes: classesOverride });
  return (
    <>
      <Button classes={classes}>Button1 in Child useStyles</Button>
      <Button classes={classesOverride}>Button2 in Child useStyles</Button>
    </>
  );
};
const AnotherChildUseStyles = props => {
  const classes = useChildStyles(props);
  return (
    <>
      <Button classes={classes}>Button3 in Child useStyles</Button>
    </>
  );
};
const ParentUseStyles = () => {
  const classes = useParentStyles();
  return <>
    <ChildUseStyles classes={classes} />
    <AnotherChildUseStyles classes={classes} />
  </>
};

export default ParentUseStyles;

enter image description here

https://codesandbox.io/s/passing-classes-using-usestyles-6x5hf?file= / demo.tsx

Кажется, нет никакого способа получить желаемый эффект, который я получил с помощью Style. Несколько вопросов, учитывая, что я все еще хочу тот же эффект (зеленая кнопка, желтый текст), используя некоторый метод переопределения классов (который, казалось, имел смысл для меня раньше).

  • Как мое понимание неверно о том, как передавать классы как средство переопределения их частей, используя useStyles?
  • Как мне подходить к этому альтернативно?
  • И если я использую неправильный подход, почему все-таки материальный пользовательский интерфейс все еще дает мне предупреждение, когда у родителя есть что-то в стилях, которых нет у ребенка?

    ключ something, предоставленный классу prop, не реализован в [Child]

  • Является ли переход от старого подхода (withStyles) к новому подходу документированным где-нибудь?

Кстати, я знаю это решение , но это кажется громоздким, когда у вас слишком много, вы хотите переопределить.

const useStyles = makeStyles({
  root: {
    backgroundColor: 'red',
    color: props => props.color, // <-- this
  },
});

function MyComponent(props) {
  const classes = useStyles(props);
  return <div className={classes.root} />;
}

1 Ответ

1 голос
/ 01 мая 2020

withStyles имеет очень мало функциональности. Это почти исключительно оболочка для обеспечения интерфейса HO C для makeStyles / useStyles . Таким образом, все функции из withStyles по-прежнему доступны с makeStyles.

Причина, по которой вы не получаете желаемый эффект, заключается просто в порядке выполнения.

Вместо:

const useParentStyles = makeStyles(parentStyles);
const useChildStyles = makeStyles(childStyles);

у вас должно быть:

const useChildStyles = makeStyles(childStyles);
const useParentStyles = makeStyles(parentStyles);

Edit Passing classes using useStyles

Порядок, в котором вызывается makeStyles, определяет порядок соответствующие таблицы стилей в <head> и когда специфика в остальном одинакова, этот порядок определяет, какие стили выигрывают (более поздние стили выигрывают у более ранних стилей). Труднее ошибиться в этом порядке, используя withStyles, так как обертка, которую вы используете для переопределения чего-то другого, обычно определяется после того, как он обернут. При множественных вызовах makeStyles проще выполнить произвольный порядок, который не обязательно помещает переопределения после базовых стилей, на которые они должны воздействовать.

Ключом к пониманию этого является признание того, что вы не действительно передавая переопределения, а скорее набор классов, которые будут объединены с новыми классами. Если childClasses.root === 'child_root_1' и parentClasses.root === 'parent_root_1', то объединенный результат равен mergedClasses.root === 'child_root_1 parent_root_1', что означает, что любые элементы, для которых для className установлено значение mergedClasses.root, получают оба CSS класса. Конечный результат (насколько то, что переопределяет) полностью определяется CSS спецификой стилей в двух классах.

Связанные ответы:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...