동적으로 제어되는 React 양식 만들기
9933 단어 reactformjavascript
이 자습서에서는 DCF를 사용하여 재료와 단계를 분리하는 간단한 레시피 양식을 만듭니다.
이 튜토리얼에서는 React를 사용하여 양식을 생성하는 방법을 다룰 것입니다.
구체적으로 다음을 수행합니다.
상태에서 레시피 구성
새 React 앱에서 양식에 대한 구성 요소를 만듭니다.
touch AddRecipeForm.js
생성자는 양식 데이터를 상태로 유지합니다. 레시피에 제목, 요약, 재료(이름 및 양) 및 단계가 있어야 합니다.
constructor(){
super()
this.state={
title:"",
summary: "",
ingredients: [
{name: "", amount: ""}
],
steps: []
}
}
보시다시피 제목과 요약 정보도 보유하고 있습니다. 이 정보는 배열에 보관할 필요가 없으므로 둘 모두에 대해 하나의 handleChange 함수를 사용할 수 있습니다.
제목 및 요약에 대한 변경 처리
사용자가 레시피의 제목과 요약을 작성할 수 있도록 단일 handleChange 함수를 작성하십시오.
handleChange = (event) => {
this.setState({
[event.target.name]: event.target.value
})
}
단계 및 성분에 대한 변경 처리
그런 다음 성분 이름, 양 및 단계 변경을 별도로 처리해야 합니다.
성분 상태 변경의 경우 다른 기능의 성분 이름과 양을 매핑해야 합니다.
handleIngredientNameChange = (e, ingredientIndex) => {
let newIngredientName = e.target.value;
this.setState((prev) => {
return {
...prev,
ingredients: prev.ingredients.map((ingredient, index) => {
if (index == ingredientIndex) {
return { ...ingredient, name: newIngredientName};
}
return ingredient;
}),
};
});
};
handleIngredientAmountChange = (e, ingredientIndex) => {
let newIngredientAmount = e.target.value;
this.setState((prev) => {
return {
...prev,
ingredients: prev.ingredients.map((ingredient, index) => {
if (index == ingredientIndex) {
return { ...ingredient, amount: newIngredientAmount};
}
return ingredient;
}),
};
});
};
단계 변경의 경우 단계를 통해 매핑하기만 하면 됩니다.
handleStepChange = (e, stepIndex) => {
let newStep = e.target.value;
this.setState((prev) => {
return {
...prev,
steps: prev.steps.map((step, index) => {
if (index == stepIndex) {
return { ...step, step_summary: newStep};
}
return step;
}),
};
});
};
성분 추가 및 제거
우리는 사용자에게 재료를 추가하고 제거할 수 있는 옵션을 제공하고자 합니다. 필터를 사용하여 성분을 제거합니다.
addIngredientInputs = () => {
this.setState((prev) => {
return {
...prev,
ingredients: [...prev.ingredients, { name: "", amount:"" }],
};
});
}
removeIngredientInput = (e, ingredientIndex) => {
e.preventDefault()
this.setState({
ingredients: this.state.ingredients.filter((ingredient, removedIngredient) => removedIngredient !== ingredientIndex )
})
}
렌더 재료
마지막으로 재료 입력을 렌더링해야 합니다. 여기에서 약간의 부트스트랩 스타일을 사용했습니다.
renderIngredientInputs = () => {
return this.state.ingredients.map((ingredient, index) => {
return (
<div key={`name ${index}`}
className="form-group">
<input className="mb-3"
value={this.state.ingredients[index].name}
onChange={(e) => this.handleIngredientNameChange(e, index)}
placeholder="Name"
name="name"
/>
<input
value={this.state.ingredients[index].amount}
onChange={(e) => this.handleIngredientAmountChange(e, index)}
placeholder="Amount"
name="amount"
/>
<br></br>
<Button variant="outline-secondary" onClick={(e)=>this.removeIngredientInput(e,index)}>{this.state.ingredients[index].name ? `Delete ${this.state.ingredients[index].name}` : `Delete Ingredient`}</Button>
</div>
);
});
};
여기에서 렌더링된 각 성분에 인덱스를 할당합니다. onChange 이벤트를 렌더에 배치하고 필요한 경우 재료를 제거하는 버튼도 추가합니다.
단계 추가 및 제거
단계를 추가하고 제거하는 것은 조금 더 간단하지만 동일한 논리를 따릅니다.
addStepInputs = () => {
this.setState((prev) => {
return {
...prev,
steps: [...prev.steps, ""],
};
});
};
removeStepInput = (e, stepIndex) => {
e.preventDefault()
this.setState({
steps: this.state.steps.filter((step, removedStep) => removedStep !== stepIndex )
})
}
재료와 마찬가지로 사용자에게 단계를 추가하거나 제거할 수 있는 옵션을 제공합니다. 그런 다음 단계 입력을 렌더링합니다.
렌더링 단계 입력
다시 말하지만, 저는 스타일링을 위해 약간의 부트스트랩을 사용했습니다. 여기서 고려해야 할 중요한 사항은 각 단계에 번호가 매겨져 있다는 것입니다. 단계가 추가되면 개수에 하나를 추가합니다.
Step${index+1}
단계를 삭제하면 해당 단계가 삭제된 위치에 따라 개수가 변경됩니다. 인덱스가 0에서 시작하기 때문에 +1을 사용해야 합니다.renderStepInputs = () => {
}
return this.state.steps.map((step, index) => {
return (
<div key={index} className="form-group">
<fieldset>
<textarea
placeholder={`Step${index+1}`}
name="rec_steps"
id="textArea"
className="form-control"
onChange={(e) => this.handleStepChange(e, index)}
value={step.step_summary}
/>
<button className="btn btn-secondary" type="button" onClick={(e)=>this.removeStepInput(e,index)}>{`Delete Step ${index+1}`}</button>
</fieldset>
</div>
);
});
};
handleStepChange = (e, stepIndex) => {
let newStep = e.target.value;
this.setState((prev) => {
return {
...prev,
steps: prev.steps.map((step, index) => {
if (index == stepIndex) {
return { ...step, step_summary: newStep};
}
return step;
}),
};
});
};
작성 핸들 제출
마지막으로, 데이터를 백엔드로 보내고 사용자를 재료 페이지로 되돌리는 handleSubmit 함수를 작성하십시오.
handleSumbit = (e) => {
e.preventDefault()
this.props.onAddRecipe(this.state)
this.props.history.push('/')
}
렌더 기능에 모두 합치기
렌더링 기능에서 양식을 작성합니다.
<h1>Add a new recipe!</h1>
<form onSubmit={this.handleSumbit} >
<fieldset>
<div class="form-group">
<label for="inputDefault">Title</label>
<input
type="inputDefault"
name="title"
class="form-control"
id="inputDefault"
placeholder="Enter title"
onChange={this.handleChange}
></input>
</div>
<div className="form-group">
<label forHtml="textArea">Summary </label>
<textarea
className="form-control"
id="textArea"
rows="3"
name="summary"
onChange={this.handleChange}
placeholder="80 characters max"></textarea>
</div>
여기에는 많은 일들이 있지만 그 중 많은 것들이 문체에 관한 것입니다. onChange 이벤트는 제목 및 요약 변경 사항을 처리합니다.
아래에 재료 및 단계 입력 필드를 추가했습니다.
<div class="form-group">
<label>Ingredients</label>
{this.renderIngredientInputs()}
<button type="button" className="btn btn-primary" onClick={()=> this.addIngredientInputs()}>+ Add Ingredient</button>
</div>
<div class="form-group">
<label forHtml="textArea">Steps</label>
{this.renderStepInputs()}
<button type="button" className="btn btn-primary" onClick={()=> this.addStepInputs()}>+ Add Step</button>
</div>
마지막으로 submit 함수에 연결된 버튼을 작성합니다.
<input type="submit" className="btn btn-secondary"></input>
</fieldset>
</form>
</div>
<div className="col-4"></div>
</div>
요약
이 튜토리얼에서는 동적으로 제어되는 추가 레시피 양식을 작성했습니다. 우리는 단계와 함께 성분과 그 양을 추가할 수 있습니다. 필요한 경우 이 정보를 삭제할 수도 있습니다.
Reference
이 문제에 관하여(동적으로 제어되는 React 양식 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kahawaiikailana/creating-a-react-dynamically-controlled-form-5dcc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)