Stellen Sie den Optionsfeldwert in Reagieren ein
Ich mache eine einfache Reaktions-App mit Formular, das Optionsfelder hat.
Hier sind Standarddaten verfügbar wie:
const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];
Anforderung:
-> Sie müssen dies wiederholen defaultData
und den jeweiligen ContactMode
Modus zuweisen, wie in jeder Zeile markiert .
Arbeitsausschnitt:
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>
Erwartete Ausgabe:
Contact Mode Email Text Both (Checked)
Contact Mode Email Text(Checked) Both
Contact Mode Email Text(Checked) Both
Hinweis: Ich kann das Namensattribut nicht ändern name="ContactMode"
. Grund dafür ist, dass ich in jeder Zeile eine eigene Schaltfläche zum Speichern habe und beim Klicken auf diese Schaltfläche zum Speichern diese bestimmte Zeile gespeichert wird. Und jede Zeile sollte haben name="ContactMode"
.
Bearbeiten:
Da meine Frage nicht klar ist, was ich erreichen möchte, werde ich hier den gesamten Code angeben.
-> Ich habe ein Schrittformular, in dem Schritt 2 der Beschäftigungsabschnitt ist, und standardmäßig habe ich die Werte, die in das Formular gesetzt werden sollen.
const dynamicData = [
{
EmploymentID: 1,
companyName: 'Company One',
designation: 'Designation One',
ContactMode: 3,
},
{
EmploymentID: 2,
companyName: 'Company two',
designation: 'Designation One',
ContactMode: 2,
},
];
-> Innerhalb des useEffect
Hakens setze ich den Formularwert wie folgt:
React.useEffect(() => {
setExpanded(0);
setValue((prev) => {
const companyDetails = [...dynamicData];
return { ...prev, companyDetails };
});
}, []);
Hier werden die Formularwerte mit Eingabefeldern ordnungsgemäß gebunden, der Optionsfeldwert wird jedoch nicht aktiviert.
-> Es sind zwei Daten verfügbar, aber die erste wird standardmäßig erweitert und die zweite wird durch Klicken auf die Expand
Schaltfläche unter der ersten geöffnet .
-> Beim Klicken auf die save
Schaltfläche wird dieses bestimmte Objekt ( inputField
) zusammen mit geänderten Daten in der Konsole protokolliert (nur Testen).
Hier ist das Problem, wenn wir die Daten ändern, dann funktionieren die Dinge gut, aber das Radio-Checked-Attribut allein macht das Element nicht überprüft. (Überprüfte Anzeige funktioniert nicht).
Fahren Sie mit Schritt 2 in der unten angegebenen Codesandbox fort, um das Problem anzuzeigen. Um das zweite Element anzuzeigen, klicken Sie auf die Schaltfläche zum Erweitern.
Bitte helfen Sie mir, den Standardwert für das Optionsfeld in jeder Zeile festzulegen.
Antworten
In Ihrer Sandbox konnte ich die Optionsfelder zum Laufen bringen
- Bereitstellung einer eindeutigen Funktion
name
für jede zugeordnete Funkgruppe - Aktualisieren Sie den Änderungshandler, um die
ContactMode
Eigenschaft eindeutig zu behandeln .
Aktualisieren Sie die Funkgruppen, um den aktuellen zugeordneten Index zu verwenden, damit sie für alle zugeordneten Gruppen eindeutig sind.
<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>
Im handleInputChange
Add auf einen Fall zu behandeln ContactMode
speziell.
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 };
});
};
Ich denke, aufgrund dessen, dass alle Funkgeräte das gleiche Namensattribut haben, sollte jede Gruppe einen anderen Namen haben. zum Beispiel:
name = " ex1"
name = "ex2"
name = "ex3"
für jede neue Gruppe fälliger Name wie dieser. wenn Sie den gleichen Namen tun es alles machen verkorkste andere denken , dass Sie ==
statt===
item.ContactMode == 3
es ist besser zu benutzen ===
@ TalOrlanczyks Antwort ist richtig. Sie drucken insgesamt 9 Optionsfelder und alle haben den gleichen Wert im Namensattribut. Technisch ist es also so, als hätte man eine Radiogruppe mit 9 Optionsfeldern, was bedeutet, dass eine Radiogruppe nur einen Wert akzeptieren kann. Ich habe Ihren Code ausgeführt und nur "Text" in der 3. Zeile ausgewählt.
Wenn Sie versuchen, 3 separate Zeilen (Funkgruppen) zu haben, müssen Sie Folgendes versuchen:
<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)}
/>{" "}
Probieren Sie es aus und führen Sie Ihren Code erneut aus
Hier sind einige Probleme in Ihrem Code ...
Jedes Mal, wenn die Komponente zurückkehrt,
.map
wird die aufgerufendefaultData
. Daher nicht dem Zustand zugeordnet.Wenn Sie für jede Iteration den gleichen Namen möchten, müssen Sie
<form>
für jede Iteration alle anderen Optionsfelder zusammen gruppieren. Daher wird nur das letzte Optionsfeld als markiert angezeigt.Es ist besser zu verwenden
===
als==
Ich habe Ihren Code geändert und defaultData
wird verwendet, um den Status zu initialisieren.
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>