2

I have a React component that renders an array with an input field and a radio button. The input field is working fine but when clicking the radio button even though the state gets updated, the value is not reflected in the UI.

Following is the implementation of the React component

import React, { useState } from 'react';
import './style.css';

export default function App() {
  const [subTemplate, setSubTemplate] = useState([
    { name: 'main', outputFormat: 'html' },
    { name: 'something else', outputFormat: 'text' }
  ]);

  const handleInputChange = (value, row, key) => {
    const updatedSubTemplate = subTemplate.map(item => {
      if (item.name === row.name) {
        return {
          ...item,
          [key]: value
        };
      }
      return item;
    });
    console.log('updatedSubTemplate', updatedSubTemplate); // updatedSubTemplate consists of the modified value 
    setSubTemplate(updatedSubTemplate);
  };

  const renderSubTemplates = () => {
    return subTemplate.map((item, index) => {
      return (
        <div key={index}>
          <input
            type="text"
            value={item.name}
            onChange={e => {
              handleInputChange(e.target.value, item, 'name');
            }}
          />
          <div>
            <input
              type="radio"
              name="html"
              checked={item.outputFormat === 'html'}
              onChange={e => {
                handleInputChange(e.target.name, item, 'outputFormat');
              }}
            />
            HTML
          </div>
          <div>
            <input
              type="radio"
              name="text"
              checked={item.outputFormat === 'text'}
              onChange={e => {
                handleInputChange(e.target.name, item, 'outputFormat');
              }}
            />
            TEXT
          </div>
        </div>
      );
    });
  };
  return <div>{renderSubTemplates()}</div>;
}

Following is a stackblitz link for the above implementation : https://stackblitz.com/edit/react-ugat24

Note: The radio button works as expected if there's only 1 element in the array.

Erick
  • 1,098
  • 10
  • 21

2 Answers2

3

It is because you have different value in name attribute.

Radio buttons are used to select one option from a list of options. so they need to have the same name to group them .

 <input
    type="radio"
    name={`group-${index}`}
    checked={item.outputFormat === 'html'}
    onChange={e => {
         handleInputChange('html', item, 'outputFormat');
    }}
  />

Working Sample

https://stackblitz.com/edit/react-4xxpev

Shyam
  • 5,292
  • 1
  • 10
  • 20
1

There are 2 issues in your code.

  • You are passing the same name attribute for all the radio inputs.
  • You are passing the wrong value for the radio elements.

Use template literals to append the index value to each set of radio group elements in the array.

Here's working code

References

Hemand S
  • 77
  • 1
  • 5