ReactJ에서 제어된 구성 요소를 사용하여 동적 형태를 구현하는 방법은 무엇입니까?
참고 자료에서 예시를 보고 있습니다.controlled form components
react.js 공식 웹사이트에서, 저는 어떻게 이 웹 사이트를 구현해야 하는지 궁금합니다.form
할 수 있는 일이라면remove
그리고.add
input
제어된 컴포넌트가 되도록 동적으로 요소를 구성합니까?이게 가능하기나 해?
예를 들면, 다음과 같습니다.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
업무 특성상, 저는 종종 그러한 양식을 구현해야 하는 자신을 발견합니다.더군다나, 나는 없다.add
또는remove
input
요소 직접 - 커스텀 컴포넌트를 관리하고 있습니다만, 간단하게 하기 위해서 기본적인 폼 요소를 요구하고 있습니다.
입력 요소를 동적으로 추가/삭제하려면 어떻게 해야 합니까?
네, 가능합니다.추가/삭제가 가능합니다.input
요소들dynamically
하지만 그러기 위해서는 몇 가지 사항을 주의해야 합니다.
1-이벤트의 적절한 바인딩.
2- 각 입력 요소의 값을 별도로 저장하는 배열입니다.
3- 사용자가 입력 요소의 값을 채우면 해당 상태에서의 특정 값만 업데이트됩니다.
논리:
값을 저장하는 배열 내부 상태를 유지합니다.#array.map을 사용하여 각 어레이 값에 대한 UI(입력 요소)를 만듭니다.필드를 만드는 동안 제거 사용button
각 필드를 사용하여 필드 인덱스를 통과합니다.function
삭제할 필드를 식별하는 데 도움이 됩니다.다음과 같은 작업을 수행합니다.onChange
또한.
다음의 예를 확인해 주세요.
class App extends React.Component {
constructor(props) {
super(props);
this.state = { values: [] };
this.handleSubmit = this.handleSubmit.bind(this);
}
createUI(){
return this.state.values.map((el, i) =>
<div key={i}>
<input type="text" value={el||''} onChange={this.handleChange.bind(this, i)} />
<input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>
</div>
)
}
handleChange(i, event) {
let values = [...this.state.values];
values[i] = event.target.value;
this.setState({ values });
}
addClick(){
this.setState(prevState => ({ values: [...prevState.values, '']}))
}
removeClick(i){
let values = [...this.state.values];
values.splice(i,1);
this.setState({ values });
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.values.join(', '));
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
{this.createUI()}
<input type='button' value='add more' onClick={this.addClick.bind(this)}/>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='container'/>
동작 확인jsfiddle
: https://jsfiddle.net/mayankshukla5031/ezdxg224/
기능 컴포넌트에서 입력 요소를 동적으로 추가/제거하는 방법
선택한 답변과 동일한 컴포넌트가 검토되어 기능 컴포넌트로 다시 작성되었습니다.
import React from 'react';
import { useState } from 'react';
function DynamicInput() {
const [values, setValues] = useState({ val: []});
function createInputs() {
return values.val.map((el, i) =>
<div key={i}>
<input type="text" value={el||''} onChange={handleChange.bind(i)} />
<input type='button' value='remove' name={i} onClick={removeClick.bind(i)} />
</div>
);
}
function handleChange(event) {
let vals = [...values.val];
vals[this] = event.target.value;
setValues({ val: vals });
}
const addClick = () => {
setValues({ val: [...values.val, '']})
}
const removeClick = (event) => {
let vals = [...values.val];
let index = Number(event.target.name);
vals.splice(index, 1);
setValues({ val: vals });
}
const handleSubmit = event => {
alert('A name was submitted: ' + values.val.join(', '));
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
{createInputs()}
<input type='button' value='add more' onClick={addClick} />
<input type="submit" value="Submit" />
</form>
);
}
export default DynamicInput;
입력 필드가 많기 때문에 개체를 사용하는 경우 다음을 수행할 수 있습니다.
class App extends React.Component {
constructor(props) {
super(props);
this.state = { values: [] };
this.handleSubmit = this.handleSubmit.bind(this);
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = { values: [{question: '',response: ''}] };
this.handleSubmit = this.handleSubmit.bind(this);
}
createUI(){
return this.state.values.map((el, i) =>
<div key={i}>
<input type="text" value={el.question} onChange={this.handleChange.bind(this, i)} />
<textarea type="text" value={el.response} onChange={this.handleChange.bind(this, i)} />
<input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>
</div>
)
}
handleChange (i,event) {
let values = [...this.state.values];
values[i][event.target.id] = event.target.value;
this.setState({ values });
}
addClick(){
this.setState(prevState => ({ values: [...prevState.values, {question: '',response: '',}]}))
}
removeClick(i){
let values = [...this.state.values];
values.splice(i,1);
this.setState({ values });
}
handleSubmit(event) {
event.preventDefault();
alert(this.state.values.map(objet=> "{"+ " " + "'question' :" + " " + objet.question + " " + "'response' :" + " " + objet.response +" " + "}") );
}
render() {
return (
<form onSubmit={this.handleSubmit}>
{this.createUI()}
<input type='button' value='add more' onClick={this.addClick.bind(this)}/>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<!-- begin snippet: js hide: false console: true babel: false -->
<input type="text" value={el.response} onChange={this.handleChange.bind(this, i)} id="response" a />
<input type='button' value='remove' onClick={this.removeClick.bind(this, i)}/>
</div>
)
}
handleChange (i,event) {
let values = [...this.state.values];
values[i][event.target.id] = event.target.value;
this.setState({ values });
}
addClick(){
this.setState(prevState => ({ values: [...prevState.values, {question: '',response: '',}]}))
}
removeClick(i){
let values = [...this.state.values];
values.splice(i,1);
this.setState({ values });
}
handleSubmit(event) {
event.preventDefault();
alert(this.state.values.map(objet=> "{"+ " " + "'question' :" + " " + objet.question + " " + "'response' :" + " " + objet.response +" " + "}") );
}
render() {
return (
<form onSubmit={this.handleSubmit}>
{this.createUI()}
<div className="d-flex justify-content-end">
<KamaminiButton onClick={this.addClick.bind(this)} text='Ajouter une autre question' />
</div>
<input type="submit" value="Submit" />
</form>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='container'/>
useRef() 훅을 사용하여 보다 간단한 방법을 찾은 것 같습니다.입력 수가 다양한 폼에 대한 참조를 유지하고 입력 추가 및 삭제 버튼을 사용합니다.그런 다음 전송 시 childNodes() 함수를 사용하여 모든 값을 가져옵니다.
form.filename:
import React, { useState, useRef } from 'react'
const Form = () => {
const formRef = useRef(null)
const [numInputs, setNumInputs] = useState(1)
const submitHandler = () => {
let inputs = formRef.current.childNodes
for (let i = 0; i < numInputs; i++) {
console.log(inputs[i].value)
}
}
return (
<form ref={formRef}>
{Array.from(Array(numInputs)).map((_, i) => (
<input type="text" />
))}
</form>
<button onClick={() => setNumInputs(numInputs - 1)}>Remove input</button>
<button onClick={() => setNumInputs(numInputs + 1)}>Add input</button>
<button onClick={submitHandler}>Submit</button>
)
}
자신의 상태 또는 다른 컴포넌트에서 전달받은 소품을 사용하여 폼을 쉽게 결정할 수 있습니다.
다음은 멍청한 예입니다.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
let myForm;
if(this.props.someprop == true){
myForm = (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange= {this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
else if(this.state.statevar == "expectedValue"){
myForm = (
// other HTML with embedded JS here
);
}
return (
{myForm}
);
}
}
확실히 하기 위해 렌더링 방식으로 했지만 모든 로직은 보조 기능으로 이동할 수 있습니다.
import React, { Component, } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
var childJson = []
export default class AddInvoice extends Component {
constructor(props) {
super(props);
this.state = {
Json: [],
rows: [{}]
}
}
handleChange = idx => e => {
const { name, value } = e.target;
const rows = [...this.state.rows];
rows[idx] = { [name]: value };
this.setState({ rows });
console.log(`rows-->>${this.state.rows[idx].amount}`);
childJson.push(this.dynamicJson(this.state.rows, idx))
this.setState({ Json: childJson })
};
handleAddRow = () => {
const item = {
name: "",
mobile: "",
btn: ""
};
this.setState({
rows: [...this.state.rows, item]
});
};
handleRemoveRow = (idx) => {
this.state.rows.splice(idx, 1);
this.setState({ rows: this.state.rows });
};
dynamicJson(rows, index) {
return {
"service": rows[index].text,
"tax": rows[index].tax,
"amount": rows[index].amount
}
};
render() {
return (
<div className="ui one column grid">
<div className=" row">
<div className="one wide computer one wide tablet one wide mobile column">
</div>
<div className="fourteen wide computer fourteen wide tablet fourteen wide mobile column">
<h1 id="title_header">INVOICE-ADD NEW</h1>
</div>
<div className="one wide computer one wide tablet one wide mobile column">
</div>
</div>
<div className=" row">
<div className="one wide computer one wide tablet one wide mobile column">
</div>
<div className="fourteen wide computer fourteen wide tablet fourteen wide mobile column">
<div id="#cus_segment" className="ui segment" style={{ backgroundColor: '#f5f5f5' }}>
<div className="ui form">
<div className="ui stackable grid">
<div className="six wide column">
<div className="field">
<label>Invoice No</label>
<input type="text" name="invoiceno" placeholder="Invoice No" value={this.state.invoiceno} onChange={e => this.setState({ invoiceno: e.target.value })} />
</div>
</div>
<div className=" six wide column">
<div className="field">
<label>Customer</label>
<select className="ui fluid selection search dropdown" name="customer" value={this.state.customer} onChange={e => this.setState({ customer: e.target.value })}>
<option defaultValue="">select</option>
<option value="sohanpatil@gmail.com">sohanpatil@gmail.com</option>
<option value="mayurawati@gmail.co">mayurawati@gmail.com</option>
<option value="nasirpatel@gmail.com">nasirpatel@gmail.com</option>
<option value="nandkishorshinde@gmail.com">nandkishorshinde@gmail.com</option>
</select>
</div>
</div>
<div className="one row">
<div className="six wide column">
<div className="field">
<label>Invoice Date</label>
<div className="ui calendar" id="calender1">
<div className="ui input right icon">
<i className="calendar icon"></i>
<input type="text" placeholder="Invoice Date" value={this.state.invoicedate} onBlur={e => this.setState({ invoicedate: e.target.value })} />
</div>
</div>
</div>
</div>
<div className="six wide column">
<div className="field">
<label>Due Date</label>
<div className="ui calendar" id="calender2">
<div className="ui input right icon">
<i className="calendar icon"></i>
<input type="text" placeholder="Due Date" value={this.state.duedate} onBlur={e => this.setState({ duedate: e.target.value })} />
</div>
</div>
</div>
</div>
</div>
<div className="two row">
<div className="six wide column">
<div className="field">
<label>Header</label>
<input type="text" name="header" placeholder="Header" value={this.state.header} onChange={e => this.setState({ header: e.target.value })} />
</div>
</div>
<div className="six wide column">
<div className="field">
<label>Remark</label>
<input type="text" name="remark" placeholder="Remark" value={this.state.remark} onChange={e => this.setState({ remark: e.target.value })} />
</div>
</div>
</div>
<div className="three row">
<div className="ten wide column">
<button className="ui primary button" type="submit">Save</button>
<button className="ui button" type="submit">Clear</button>
<button className="ui button" type="submit">Cancel</button>
</div>
</div>
<div className="foure row">
<div className="one wide column">
<div className="field">
<h4 style={{ textAlign: "center", borderRadius: 2 }}>Action</h4>
</div>
</div>
<div className="two wide column" style={{ marginLeft: 55 }}>
<div className="field">
<h4 style={{ textAlign: "center", borderRadius: 2 }}>Text</h4>
</div>
</div>
<div className="three column" style={{ marginLeft: 200 }}>
<div className="field">
<h4 style={{ textAlign: "center", borderRadius: 2 }}>Tax</h4>
</div>
</div>
<div className="foure wide column" style={{ marginLeft: 190 }}>
<div className="field">
<h4 style={{ textAlign: "center", borderRadius: 2 }}>Amount</h4>
</div>
</div>
</div>
{this.state.rows.map((item, idx) => (
<div className="five row" id="addr0" key={idx} >
<div className="one wide column">
<div className="field">
<div className="ui icon" style={{ backgroundColor: "#f76060", color: "white", height: 35, width: 40, textAlign: "center", borderRadius: 2 }} onClick={() => this.handleRemoveRow(idx)}>
<i className="trash alternate icon" style={{ marginTop: 8 }}></i>
</div>
</div>
</div>
<div className="five wide column">
<div className="field">
<input type="text" name="text" placeholder="text" value={this.state.rows[idx].text} onChange={this.handleChange(idx)} />
</div>
</div>
<div className="three wide column">
<div className="field">
<select className="ui fluid selection search dropdown " name="tax" id="tax_dropdown" value={this.state.rows[idx].tax} onChange={this.handleChange.bind(this)}>
<option defaultValue="">Select</option>
<option value="STAX">STAX</option>
<option value="VAT">VAT</option>
</select>
</div>
</div>
<div className="three wide column">
<div className="field">
<input type="text" name="amount" placeholder="amount" value={this.state.rows[idx].amount} onChange={this.handleChange(idx)} />
</div>
</div>
</div>
))}
<div className="six row">
<div className="two wide column">
<div className="field">
<div className="ui icon" style={{ backgroundColor: "#c4d3d3", height: 35, width: 55, textAlign: "center", borderRadius: 2 }} onClick={this.handleAddRow}>
<i className="plus icon" style={{ marginTop: 8 }}></i>
<label>Add</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="one wide computer one wide tablet one wide mobile column">
</div>
</div>
</div>
);
}
}
언급URL : https://stackoverflow.com/questions/42316604/how-to-implement-a-dynamic-form-with-controlled-components-in-reactjs
'programing' 카테고리의 다른 글
패키지에 반응하는 종속성을 추가하는 올바른 방법은 무엇입니까?반응 성분용 json (0) | 2023.03.31 |
---|---|
Redux에서 mapStateToProps를 사용하지 않고 mapDispatchToProps를 매핑할 수 있습니까? (0) | 2023.03.31 |
WordPress NinjaForms JavaScript API 제출 전 (0) | 2023.03.31 |
의 필드를 무시합니다.[Xml Ignore]와 유사한 NET JSON 시리얼화 (0) | 2023.03.31 |
Woocommerce - 제품 종류 링크 방법 (0) | 2023.03.31 |