React에서 라디오 버튼 값 설정

Nov 24 2020

라디오 버튼이있는 폼으로 간단한 반응 앱을 만들고 있습니다.

여기에 사용할 수있는 기본 데이터가 있습니다.

const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

요구 사항 :

-> 이것을 반복 하고 각 행에서 확인 된대로 defaultData각각의 ContactMode모드를 할당해야 합니다.

작업 스 니펫 :

const { useState } = React;

const App = () => {
  const [formValue, setFormValue] = useState({
    ContactMode: 1
  });

  const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

  const handleInputChange = (e, index) => {
    const { name, value } = event.target;
    setFormValue({
      ...formValue,
      [name]: value
    });
  };

  const submitData = () => {
    console.log(formValue);
  };

  return (
    <div>
      <form>
        {defaultData.map((item, index) => {
          return (<React.Fragment>
            <label> Contact Mode </label>
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 1}
              value={1}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Email
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 2}
              value={2}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Text
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 3}
              value={3}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Both
            <br />
            <br />
            <button type="button">
               Save
             </button>
            <br />
            <br />
            <br />
          </React.Fragment>);
        })}
      </form>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

예상 출력 :

Contact Mode  Email Text Both (Checked)

Contact Mode  Email Text(Checked) Both

Contact Mode  Email Text(Checked) Both

참고 : 이름 속성을 수정할 수 없습니다 name="ContactMode".. 이유는 각 행에 개별 저장 버튼이 있고 해당 저장 버튼을 클릭하면 특정 행이 저장됩니다. 각 행에는 name="ContactMode"..

편집하다:

내 질문이 내가 달성하려는 것에 대해 명확하지 않기 때문에 여기에 전체 코드를 제공 할 것입니다.

-> 2 단계가 고용 섹션이고 기본적으로 양식에 설정할 값이있는 스테퍼 양식이 있습니다.

const dynamicData = [
  {
    EmploymentID: 1,
    companyName: 'Company One',
    designation: 'Designation One',
    ContactMode: 3,
  },
  {
    EmploymentID: 2,
    companyName: 'Company two',
    designation: 'Designation One',
    ContactMode: 2,
  },
];

-> 내부 useEffect후크는 다음과 같이 양식 값을 설정합니다.

  React.useEffect(() => {
    setExpanded(0);
    setValue((prev) => {
      const companyDetails = [...dynamicData];
      return { ...prev, companyDetails };
    });
  }, []);

여기에서 입력 상자가있는 양식 값은 올바르게 바인딩되지만 라디오 버튼 값은 확인되지 않습니다.

-> 두 개의 데이터를 사용할 수 있지만 첫 번째 데이터는 기본적으로 확장되고 두 번째 데이터는 첫 번째 데이터 Expand아래의 버튼 을 클릭하면 열립니다 .

-> 의 클릭시 save버튼, 특정 개체 ( inputField) 콘솔 수정 데이터와 함께 (유일한 테스트)가 기록 될 것이다 ..

여기서 문제 는 데이터를 수정하면 잘 작동하지만 라디오 검사 속성만으로는 항목을 확인하지 않습니다. (확인 표시가 작동하지 않음) ..

문제를 확인하려면 아래 제공된 코드 및 상자의 2 단계로 이동하십시오. 두 번째 항목을 보려면 확장 버튼을 클릭하십시오.

각 행에 기본 라디오 버튼 값을 설정하도록 친절하게 도와주세요.

답변

1 DrewReese Nov 25 2020 at 14:15

당신의 샌드 박스에서 라디오 버튼이 작동하도록 할 수있었습니다.

  1. name매핑 된 각 라디오 그룹에 고유 한 제공
  2. ContactMode속성 을 고유하게 처리하도록 변경 처리기를 업데이트합니다 .

모든 매핑 된 그룹 중에서 고유하게 만들기 위해 현재 매핑 된 색인을 사용하도록 라디오 그룹을 업데이트합니다.

<div className="form-group col-sm-4">
  <label className="inline-flex items-center mr-6">
    <input
      type="radio"
      className="form-radio border-black"
      name={`ContactMode-${index}`} // <-- append index to name value={1} checked={inputField.ContactMode === 1} // <-- use strict "===" onChange={(event) => handleInputChange(index, event)} /> <span className="ml-2">Email</span> </label> </div> <div className="form-group col-sm-4"> <label className="inline-flex items-center mr-6"> <input type="radio" className="form-radio border-black" name={`ContactMode-${index}`}
      value={2}
      checked={inputField.ContactMode === 2}
      onChange={(event) => handleInputChange(index, event)}
    />
    <span className="ml-2">Text</span>
  </label>
</div>
<div className="form-group col-sm-4">
  <label className="inline-flex items-center mr-6">
    <input
      type="radio"
      className="form-radio border-black"
      name={`ContactMode-${index}`}
      value={3}
      checked={inputField.ContactMode === 3}
      onChange={(event) => handleInputChange(index, event)}
    />
    <span className="ml-2">Both</span>
  </label>
</div>

handleInputChange추가하는 경우를 처리하기 위해 ContactMode특별히.

const handleInputChange = (index, event) => {
  const { name, value } = event.target;
  if (name === 'designation' && !isLettersOnly(value)) {
    return;
  }

  if (name.startsWith('ContactMode')) { // <-- check name prefix
    setValue((prev) => ({
      ...prev,
      companyDetails: prev.companyDetails.map((detail, i) =>
        i === index
          ? {
              ...detail,
              ContactMode: Number(value), // <-- store back under correct key, as number for string equality check
            }
          : detail,
      ),
    }));
    return; // <-- return early so other state update is skipped!
  }

  setValue((prev) => {
    const companyDetails = prev.companyDetails.map((v, i) => {
      if (i !== index) {
        return v;
      }

      return { ...v, [name]: value };
    });

    return { ...prev, companyDetails };
  });
};

1 TalOrlanczyk Nov 24 2020 at 22:10

모든 라디오가 같은 이름 속성을 가지고 있기 때문에 모든 그룹이 다른 이름을 가져야한다고 생각합니다. 예를 들면 :

name = " ex1"
name = "ex2"
name = "ex3"

모든 새 그룹 이름에 대해 이와 같이. 같은 이름을 사용하면 모든 것을 엉망으로 만드는 다른 사람이 ==대신 당신을 생각하게 만듭니다.===

item.ContactMode == 3

사용하는 것이 좋습니다 ===

vkvkvk Nov 24 2020 at 22:49

@TalOrlanczyk의 대답이 맞습니다. 총 9 개의 라디오 버튼을 인쇄하고 있으며 모두 이름 속성의 값이 동일합니다. 따라서 기술적으로는 라디오 버튼이 9 개있는 라디오 그룹을 갖는 것과 같습니다. 즉, 라디오 그룹은 하나의 값만받을 수 있습니다. 코드를 실행했는데 세 번째 줄에서 "텍스트"만 선택되었습니다.

3 개의 개별 행 (라디오 그룹)을 얻으려면 다음과 같이 시도해야합니다.

<input
    type="radio"
    name={"ContactMode"+index}
    checked={item.ContactMode == 1}
    value={1}
    onChange={(event) => handleInputChange(index, event)}
/>{" "}
Email
<input
    type="radio"
    name={"ContactMode"+index}
    checked={item.ContactMode == 2}
    value={2}
    onChange={(event) => handleInputChange(index, event)}
/>{" "}
Text
<input
    type="radio"
    name={"ContactMode"+index}
    checked={item.ContactMode == 3}
    value={3}
    onChange={(event) => handleInputChange(index, event)}
/>{" "}

시도하고 코드를 다시 실행하십시오.

NeetigyaChahar Nov 25 2020 at 13:16

다음은 코드의 몇 가지 문제입니다.

  1. 구성 요소가 반환 될 때마다이에서 .map호출됩니다 defaultData. 따라서 상태에 매핑되지 않습니다.

  2. 각 반복에 대해 동일한 이름을 원하면 <form>모든 반복에 대해 사용해야 합니다. 그렇지 않으면 모든 라디오 버튼이 함께 그룹화되므로 마지막 라디오 버튼 만 표시된 것으로 표시됩니다.

  3. ===대신 사용 하는 것이 좋습니다==

코드를 수정 defaultData했으며 상태를 초기화하는 데 사용됩니다.

const { useState } = React;


  const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

const App = () => {

  const [formValue, setFormValue] = useState([...defaultData]);

  const handleInputChange = (index, e) => {
    const { name, value } = e.target;

    const newFormValue = [...formValue];
    newFormValue.splice(index,1,{[name]: value});
    
    setFormValue(newFormValue);
  };

  const submitData = () => {
    console.log(formValue);
  };

  return (
    <div>
        {formValue.map((item, index) => {
          return (<form>
            <label> Contact Mode </label>
            <input
              type="radio"
              name="ContactMode"
              checked={Number(item.ContactMode) === 1}
              value={1}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Email
            <input
              type="radio"
              name="ContactMode"
              checked={Number(item.ContactMode) === 2}
              value={2}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Text
            <input
              type="radio"
              name="ContactMode"
              checked={Number(item.ContactMode) === 3}
              value={3}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Both
            <br />
            <br />
          </form>);
        })}
        <button type="button" onClick={submitData}>
          {" "}
          Submit{" "}
        </button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>