Как применить правила типа css к стилизованным компонентам в React

Имея следующий код html/css, который позволяет элементам html вести себя как радиогруппа:

.radios .radio{
    background-color:#c5e043;
    display:inline-block;
    width:20px;
    height:20px;
    cursor:pointer
}

.radios input[type=radio]{
    display:none
}

.radios input[type=radio]:checked + .radio{
    background-color:#241009
}
<div class = "radios">
<div>
    <input type = "radio" name = "rGroup"  id = "r1"  />
    <label class = "radio" for = "r1"></label>
    <input type = "radio" name = "rGroup"  id = "r2" />
    <label class = "radio" for = "r2"></label>
    <input type = "radio" name = "rGroup"  id = "r3" />
    <label class = "radio" for = "r3"></label></div>
</div>

Я хочу написать в React некоторые стилизованные компоненты, которые ведут себя одинаково, но не знаю, как писать стилизованные компоненты input[type=radio] и .radios input[type=radio]:checked + .radio.

Вот код, кодовая песочница здесь. Он показывает элементы, но щелчок не работает, он не меняет выбранный элемент, как в приведенном выше коде.

Что следует изменить?

import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";

export const XSelectionBoxContainer = styled.div`
  background-color: #c5e043;
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
`;

export const Xlabel = styled.label`
  background-color: #c5e043;
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
`;

export const Xinput = styled.input`
  display: none;
  :checked {
    background-color: #241009;
  }
`;

function App() {
  const options = [
    {
      label: "first",
      value: "first",
      name: "radio-group"
    },
    {
      label: "second",
      value: "second",
      name: "radio-group"
    },
    {
      label: "third",
      value: "third",
      name: "radio-group"
    }
  ];
  return (
    <XSelectionBoxContainer>
      {options.map((option) => {
        return (
          <div key = {option.label}>
            <Xlabel htmlFor = {option.value}></Xlabel>
            <Xinput
              type = "radio"
              name = {option.value}
              value = "1"
              id = {option.value}
            />
          </div>
        );
      })}
    </XSelectionBoxContainer>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел &quot;Заголовок&quot; в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
Как React Helmet спасает меня при разделении файлов CSS?
Как React Helmet спасает меня при разделении файлов CSS?
Многие новички могут столкнуться с проблемой, когда одна страница с CSS наследует свойства от другой страницы с другим CSS. У меня было много проблем,...
1
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно поместить компонент label под элементом input, чтобы вы могли использовать оператор + в css для стилизации элемента метки, если input — это :checked.

Обновленный код ниже:

import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";

export const XSelectionBoxContainer = styled.div`
  background-color: #c5e043;
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
`;

export const Xlabel = styled.label`
  background-color: #c5e043;
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
`;

export const Xinput = styled.input`
  display: none;
  &:checked { 
    & + label {
      background-color: #241009;
    }
  }
`;

function App() {
  const options = [
    {
      label: "first",
      value: "first",
      name: "radio-group"
    },
    {
      label: "second",
      value: "second",
      name: "radio-group"
    },
    {
      label: "third",
      value: "third",
      name: "radio-group"
    }
  ];
  return (
    <XSelectionBoxContainer>
      {options.map((option) => {
        return (
          <div key = {option.label}>
            
            <Xinput
              type = "radio"
              name = {option.name}
              value = "1"
              id = {option.value}
            />
            <Xlabel htmlFor = {option.value}></Xlabel>
          </div>
        );
      })}
    </XSelectionBoxContainer>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Кажется, что они кликабельны, но не работают как радиогруппа, она должна иметь не более одной активной одновременно, как в примере html+css. вот песочница с вашим ответом: codeandbox.io/s/stoic-mopsa-t1cjzf?file=/src/index.js

Leo Messi 14.02.2023 11:19

@LeoMessi, я обновил код. Xinput имеет атрибут имени, в котором вы передавали {option.value}. Измените его на {option.name}, чтобы сгруппировать.

the.marolie 14.02.2023 11:25

Другие вопросы по теме