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

  const [category, setCategory] = useState("");

  const handleSubmit = e => {
    console.log(e);
    setCategory(e.target.value);
  };

  return (
    <>
      <CenterAlignedColumnContainer>
        <FormHeadingText>
          <FormSectionHeadingTextContainer>
            Category
          </FormSectionHeadingTextContainer>
        </FormHeadingText>
        <CategoryContainer>
          <TextRadioButton
            value="Salads"
            onClick={handleSubmit}
            name="category"
          >
            <RadioButtonText>
              <TextContainer>Salads</TextContainer>
            </RadioButtonText>
          </TextRadioButton>
          <TextRadioButton value="Pasta" onClick={handleSubmit} name="category">
            <RadioButtonText>
              <TextContainer>Pasta</TextContainer>
            </RadioButtonText>
          </TextRadioButton>
        
        </CategoryContainer>
        <PartialWidthDivider />
      </CenterAlignedColumnContainer>
    </>
  );
}

Стилизованный div для пользовательской кнопки Radio

export const TextRadioButton = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: 10px;
  background: rgba(176, 167, 230, 0.5);
  box-shadow: 0px 4px 4px rgba(176, 167, 230, 0.5);
  border-radius: 20px;
  margin-left: -10px;
  margin: 8px;
`;

0
user13909231 19 Июл 2020 в 16:49

3 ответа

Лучший ответ

div не имеет свойства value, поэтому вы должны ссылаться на него, то есть как на пропущенную опору:

<TextRadioButton value='something' onClick={handleSubmit(props.value)} />

И использовать это явно

handleSubmit(value) {
    setCategory(value);
}
0
k-wasilewski 19 Июл 2020 в 14:13

Таким образом, есть несколько проблем с этим, в первую очередь из-за того, что у вас есть псевдоэлемент, охватывающий весь экран:

export const Background = styled.div`
  width: 100%;
  &:before {
    display: block;
    position: absolute;
    width: 100%;
    height: 400vh;
    content: "";
    background: url(https://res.cloudinary.com/antilibrary/image/upload/v1595154947/Piatto/backgroundFormNew_sk7yie.svg)
      repeat center center;
    opacity: 0.5;
  }
`;

Когда элементом является :before, это означает, что он находится над любыми другими элементами в контексте стека, так же, как жестко закодированные элементы. Простое решение - дать псевдоэлемент z-index: -1, который обеспечит его размещение за всем остальным. В идеале, однако, вы бы вообще не использовали псевдоэлемент, а вместо этого отдельный div, помещенный абсолютно за всем.

Во-вторых, ваши кнопки не используют хороший семантический HTML, и в результате вы не сможете настроить таргетинг на value, которого нет в divs. Кроме того, поскольку текст кнопки отделен от самой кнопки, будут случаи, когда она все равно возвращает неопределенное значение, поскольку цель события не содержит значения кнопки.

Сначала я предлагаю изменить TextRadioButton на styled.button. Возможно, вам придется настроить некоторые из своих стилей, чтобы это учесть. Затем измените обработчик событий на следующий:

const handleSubmit = e => {
  const value = e.currentTarget.value;
  setCategory(value);
};

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

0
lawrence-witt 19 Июл 2020 в 14:28

Измените свой метод onClick на:

onClick={(e)=>handleSubmit(e}

Или

onClick={
 (e)=>{
   console.log(e);
   setCategory(e.target.value);
};
0
Solomon Bush 19 Июл 2020 в 14:17
62981128