Как стилизовать один и тот же компонент несколькими способами, используя CSS-модули в React? - PullRequest
0 голосов
/ 17 мая 2019

Я недавно переключился на использование CSS-модулей в своем проекте и столкнулся с небольшой проблемой.

В приведенном ниже простом примере кода я создаю компонент ввода, который я хочу использовать в качестве поля формы при создании форм.Проблема возникает, когда я хочу иметь возможность по-разному стилизовать компонент ввода в некоторых ситуациях.

FormInput.js

const FormInput = props => (
  <FormControl>
    <InputLabel>{props.label}</InputLabel>
    <Input />
  </FormControl>
);

Form.js

import React from 'react';
import Button from '@material-ui/core/Button';
import Input from './input';

const Form = () => (
  <form>
    <Input label="Name" />
    <Button> Submit </Button>
  </form>
);

Я знаю, что это можно сделать с помощью стилевых компонентов, но я действительно ищурешение, которое использует модули CSS.Любая помощь будет оценена

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

Вы можете просто импортировать CSS и передать его как prop в Input. В этом случае вы можете передать его как className.

Примечание: как вы заметите ниже, CSS может быть немного избыточным, когда дело доходит до стилизации вложенных и псевдоэлементов, поэтому я настоятельно рекомендую SASS (scss или less) для предварительно обработанных таблиц стилей (пост-обработка преобразует таблицы стилей SASS в простую таблицу стилей CSS).

Рабочий пример (многократное использование Input, но стилизация его под другое classes):

Edit React CSS Modules


компонентов / входные данные (он принимает строку className, функцию onChange (обязательно), строку label, строку name (обязательно) и строку value)

import React from "react";
import PropTypes from "prop-types";

const Input = ({ className, onChange, label, name, value }) => (
  <div className={className}>
    <label htmlFor={name}>{label}: </label>
    <input value={value} onChange={onChange} name={name} type="text" />
  </div>
);

// PropTypes ensures that passed down props adhere to the type checking
// rules defined below
Input.propTypes = {
  className: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  value: PropTypes.string
};

export default Input;

styles.css (вам нужно будет использовать camelCase вместо snake-case для className с)

.appContainer {
  text-align: center;
  padding: 20px;
}

input {
  height: 40px;
  vertical-align: middle;
  display: inline-block;
  border: 0 none;
  padding: 0 10px;
  background: #fff;
  color: #666;
  border: 1px solid #e5e5e5;
  transition: 0.2s ease-in-out;
  transition-property: color, background-color, border;
  font-size: 15px;
}

.nameField {
  font-weight: bold;
  color: blue;
  margin-bottom: 20px;
}

.nameField > input {
  color: green;
}

.emailField {
  font-weight: bold;
  color: red;
  margin-bottom: 20px;
}

.emailField > input {
  color: blue;
}

.resetButton {
  cursor: pointer;
  background-color: transparent;
  color: #222;
  border: 1px solid #e5e5e5;
  margin: 0;
  overflow: visible;
  box-sizing: border-box;
  padding: 0 30px;
  vertical-align: middle;
  font-size: 14px;
  line-height: 38px;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  transition: 0.1s ease-in-out;
  transition-property: color, background-color, border-color;
}

.resetButton:hover {
  background-color: transparent;
  color: #222;
  border-color: #b2b2b2;
}

.resetButton:focus {
  outline: none;
}

компонентов / приложение (import все css как classes и применять их по мере необходимости - вы также можете использовать ES6 деструктурирование для извлечения отдельных классов , например: import { appContainer } from "./styles.css";)

import React from "react";
import { render } from "react-dom";
import Input from "./components/Input";
import useFieldHandler from "./hooks/useFieldHandler";
import classes from "./styles.css";

const App = () => {
  const { values, handleChange, resetValues } = useFieldHandler({
    name: "",
    email: ""
  });

  return (
    <div className={classes.appContainer}>
      <h1>CSS Modules</h1>
      <Input
        label="Name"
        name="name"
        className={classes.nameField}
        value={values.name}
        onChange={handleChange}
      />
      <Input
        label="Email"
        name="email"
        className={classes.emailField}
        value={values.email}
        onChange={handleChange}
      />
      <div className={classes.btnContainer}>
        <button
          type="button"
          className={classes.resetButton}
          onClick={resetValues}
        >
          Reset
        </button>
      </div>
    </div>
  );
};

render(<App />, document.getElementById("root"));
0 голосов
/ 17 мая 2019

Итак, что я объяснил выше, это передать уникальный идентификатор как реквизит, а затем вам нужно использовать литерал шаблона, чтобы добавить его к существующему имени класса в компоненте Input.

FormInput.js

const FormInput = props => (
  <FormControl>
    <InputLabel>{props.label}</InputLabel>
    <Input uniqueClass='unique-class'/>
  </FormControl>
);
Form.js

import React from 'react';
import Button from '@material-ui/core/Button';
import Input from './input';

const Form = () => (
  <form>
    <Input uniqueClass='unique-class' label="Name" />
    <Button> Submit </Button>
  </form>
);
...