Могу ли я выбрать все реагирующие компоненты типа, не назначая класс каждому? - PullRequest
0 голосов
/ 20 сентября 2018

У меня здесь есть игровая площадка: https://codesandbox.io/s/736v9vjzw1

const Something = ({ classes, children, variant }) => {
  return (
    <div className={classes.someThing}>
      <p> I'm some thing </p>

      <SomeOtherThing />

      <SomeOtherThing> I have some children </SomeOtherThing>

      <SomeOtherThing> I have some children </SomeOtherThing>

      <SomeOtherThing> I have some children </SomeOtherThing>
    </div>
  );
};

const styles = {
  someThing: {
    color: "green",
    border: "solid 2px black",
    margin: 30,

    "& $someOtherThing": {
      backgroundColor: "pink" // Doesn't work
    },

    "& p": {
      fontWeight: "bold" //This works but is too broad
    }
  }
};

У меня есть ситуация, когда я хочу стилизовать все SomeOtherThing внутри моего SomeThing.

Я могу использовать селектор & p, чтобы выбрать элемент p - но мне это не нравится.Это будет стилизовать любые случайные p s, которые у меня есть - и я не хочу заглядывать внутрь определения компонента, чтобы найти его элемент верхнего уровня.

Как я могу это сделать?Что-то вроде & SomeOtherElement.

Реальное применение этого в том, что в некоторых местах я хочу, чтобы SomeOtherElement отображался block, а в других местах inline-block.

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Это так просто, в ваших someThing CSS-кодах выберите p элементы с классом someOtherThing именем класса и используйте not() CSS-операцию для p на верхнем уровне, см. Следующий код:

const styles = {
  someThing: {
    color: "green",
    border: "solid 2px black",
    margin: 30,

    "& [class*='SomeOtherThing']": {
      backgroundColor: "pink" // 
    },

    "& :not([class*='SomeOtherThing'])": {
      fontWeight: "bold" // Just for top level p
    }
  }
};

и

const SomeOtherThing = ({ classes, children }) => {
  return (
    <p className={classes.root}> I'm another thing {children} </p>
  );
};

CodeSandBox

Способ, которым это работает, заключается в том, что, предоставляя SomeOtherThing любой класс jss, он будет визуализироватьЭлемент dom выглядит примерно так:

 <p class="SomeOtherThing-root-0-1-2"> I'm another thing  I have some children  </p>

, с которым будет совпадать селектор атрибутов [class*='SomeOtherThing'] .

Обратите внимание, что этот селектор будет применяться и ко всем более глубоким вложенным SomeOtherThing с.

0 голосов
/ 03 октября 2018

Одна проблема с «каскадным» аспектом CSS заключается в том, что он как бы ломает компонентную модель React.Но в React вы всегда можете создать обертку или компонент более высокого порядка, который возвращает другой с некоторыми предопределенными реквизитами, что-то вроде фабричной функции:

const Something = props => {
  return (
    <div className={props.className}>
      // ...
    </div>
  )
}

const SomethingInline = props => {
  return <Something className='display-inline' {...props} />
}

const SomethingBlock = props => {
  return <Something className='display-block' {...props} />
}

const App = () => {
  return (
    <div>
      <SomethingInline />
      <SomethingBlock />
      <SomethingBlock> I have children </SomethingBlock>
    </div>
  )
}

Вместо использования селектора & для определения вашего стилясоздайте класс, который применяется только к этим конкретным версиям вашего компонента.Таким образом, глобальная область CSS исключается, и вы можете создавать такие декларативные компоненты, которые описывают их собственный стиль, но не требуют явной передачи имени класса.

0 голосов
/ 01 октября 2018

Я бы расширил компонент SomeOtherThing для принятия className и добавил бы его к div, если он присутствует.Это также будет работать на производственной установке, где имена классов уменьшены до, например, .t-0-root.

Вот раздвоенная игровая площадка: https://codesandbox.io/s/zlzx277zzm, которая показывает, как ее использовать.

const SomeOtherThing = ({ classes, children, className }) => {
  return (
    <p className={`${classes.someOtherThing} ${className && className}`}>
      I'm another thing {children}
    </p>
  );
};

Скорее всего, я бы использовал пакет classnames для условной визуализации имени класса вместо строковой интерполяции.

const Something = ({ classes, children, variant }) => {
  return (
    <div className={classes.someThing}>
      <p> I'm some thing </p>

      <SomeOtherThing />

      <SomeOtherThing className={classes.someOtherThing}>
        I have some children
      </SomeOtherThing>

      <SomeOtherThing className={classes.someOtherThing}>
        I have some children
      </SomeOtherThing>

      <SomeOtherThing className={classes.someOtherThing}>
        I have some children
      </SomeOtherThing>
    </div>
  );
};

const styles = {
  someThing: {
    color: "green",
    border: "solid 2px black",
    margin: 30
  },
  someOtherThing: {
    backgroundColor: "pink"
  }
};
...