Как вы переключаете проверенное значение переключателя в реакции, используя хуки? - PullRequest
2 голосов
/ 10 марта 2020

У меня есть группа радиокнопок, созданных из некоторых внешних данных, как показано в примерах ниже. Они отображаются и работают так, как я ожидал, за исключением атрибута aria-checked. Нажатие переключателя переключает проверенное значение, но оно остается true, когда выбрано другое.

Если я последовательно нажимаю каждый переключатель, я получаю список переключателей, отображающих aria-checked="true" что, очевидно, не лучший опыт.

Я не уверен, как go о переключении переключенного переключенного значения обратно в false, когда проверяется другое.

Любая помощь будет be great!

Ввод:

    const [isChecked, setIsChecked] = useState(false);

    <Input
        type={type}
        id={id}
        value={id}
        name={name}
        aria-label={label}
        aria-checked={isChecked}
        onChange={() => setIsChecked(!isChecked)}
    />
    <Label htmlFor={id}>{label}</Label>

Использование:

    <fieldset>
        {someData.map(item => {
            return (
                <RadioButton
                    type="radio"
                    key={item.id}
                    id={item.id}
                    name={item.name}
                    label={item.label}
                />
            );
        })}
    </fieldset>

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Вы можете попробовать что-то вроде этого.

const Radio = React.memo(function Radio({
  item,
  checked,
  onChange
}) {
  console.log("rendering", item.label);
  return (
    <label>
      {item.label}
      <input
        type="radio"
        value={item.id}
        checked={checked}
        onChange={onChange}
      />
    </label>
  );
});
const RadioList = ({ items, value, onChange }) => (
  <div>
    {items.map(item => (
      <Radio
        item={item}
        key={item.id}
        checked={item.id === value}
        onChange={onChange}
      />
    ))}
  </div>
);

const App = ({ items }) => {
  const [value, setValue] = React.useState(items[0].id);
  const [v, setV] = React.useState(items[1].id);
  const onChange = React.useCallback(
    e => setValue(e.target.value),
    []
  );
  const onOther = React.useCallback(
    e => setV(e.target.value),
    []
  );
  return (
    <div>
      <RadioList
        items={items}
        value={value}
        onChange={onChange}
      />
      <RadioList
        items={items}
        value={v}
        onChange={onOther}
      />
    </div>
  );
};
//render app
ReactDOM.render(
  <App
    items={[
      { id: "1", label: "one" },
      { id: "2", label: "two" },
      { id: "3", label: "three" },
      { id: "4", label: "four" }
    ]}
  />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
0 голосов
/ 10 марта 2020

Здесь необходимо изменить две вещи.

  1. Когда вы отображаете список переключателей в одной группе, атрибут name должен быть одинаковым для всех переключателей. , Поэтому вместо чтения атрибута имени из someData передайте один и тот же атрибут имени каждой кнопке. Или сохраните одно и то же имя в someData для каждого объекта.

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

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

const RadioButton = ({ type, id, name, label, checked, onChange }) => {
return (
    <>
        <input
            type={type}
            id={id}
            value={id}
            name={name}
            aria-label={label}
            aria-checked={checked}
            checked={checked}
            onChange={onChange}
        />
        <label htmlFor={id}>{label}</label>
    </>
)

}

const RadioGroup = () => {
const someData = [{
    id: 1,
    name: 'name',
    label: 'name 1'
}, {
    id: 2,
    name: 'name',
    label: 'name 2'
}, {
    id: 3,
    name: 'name',
    label: 'name 3'
}];

const [checkedValue, setIsChecked] = useState(1);

return (
    <fieldset>
        {someData.map(item => {
            return (
                <RadioButton
                    type="radio"
                    key={item.id}
                    id={item.id}
                    name="radioGroup"
                    label={item.label}
                    checked={checkedValue === item.id}
                    onChange={() => setIsChecked(item.id)}
                />
            );
        })}
    </fieldset>
)

} ​​

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...