React TS - Передача реквизита в дерево компонентов - PullRequest
0 голосов
/ 27 февраля 2020

Я создал элементы формы, которые я могу настроить различными способами для создания форм.

Вот пример этого:

<form>
  <Label htmlFor="name" name="Enter name:" />
  <InputWrapper>
    <Input id="name" name="name" />
  </InputWrapper>
  <CharacterLimit />
</form>

То, что я хотел бы сделать, это установить maxLength & required prop на моем компоненте Input, и у моего компонента Label появится красная звездочка (*), а у моего компонента CharacterLimit отобразится набор maxLength, установленный на моем Input component.

Вот как выглядит мой Label компонент:

interface ILabel {
  htmlFor: string;
  name: string;
  required?: boolean;
}

export const Label: React.FC<ILabel> = ({ htmlFor, name, required }) => {
  return (
    <StyledLabel htmlFor={htmlFor}>
      {name} {required && <StyledRequired>*</StyledRequired>}
    </StyledLabel>
  );
};

const StyledLabel = styled.label`
  font-weight: 600;
`;
const StyledRequired = styled.span`
  color: red;
`;

А вот как выглядят мои компоненты CharacterLimit:

interface ICharacterLimit {
  maxLength?: number;
}

export const CharacterLimit: React.FC<ICharacterLimit> = ({ maxLength }) => {
  return (
    <>
      {maxLength && (
        <StyledCharacterLimit>0 / {maxLength} Characters</StyledCharacterLimit>
      )}
    </>
  );
};

Теперь вы, наверное, задаетесь вопросом, почему я не просто помещаю компоненты Label & CharacterLimit внутри моего компонента Input и условно отображаю их таким образом.

Ну, у меня есть другой компонент как вы можете видеть под названием InputWrapper, это используется для стилизации "контейнера" ​​input, поэтому я хотел отделить этот стиль отдельно, поэтому я мог поместить input и button внутри контейнера, например.

Вот иллюстрация к примеру bette Что я имею в виду:

enter image description here

Как я могу передать реквизиты от моего компонента Input компонентам Label и CharacterLimit? Или есть другой способ добиться того же расположения на моей иллюстрации?

Я собрал демонстрационную версию CodeSandBox

1 Ответ

0 голосов
/ 27 февраля 2020

Это не обязательно ответ, но слишком долго для комментария

Примерно так:

const FormModel = () => {
  const [formModel, setFormModel] = useState();
  const updateFormModel = name => value => setFormModel({
    ...formModel,
    { [name]: value }
  });
  return (
    <form>
      <InputWrapper onChange={updateForm("something")} isValid={validate(formModel)} />
    <form>
  );
};

const InputWrapper = ({ onChange, isValid }) => {
  // returns appropriate stuff, including 
  // <input onChange={e => onChange(e.currentTarget.value)} />
  // styled based on isValid prop. May also want to debounce
  // input, but whateves.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...