Reputation: 63
I am creating a Recipe Box app but I have a problem with the input for the recipe name when I'm creating a recipe.
When I start to type in it I get the following error message:
This is my states in my main component:
class RecipeBoxContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
recipes: [
{
name: "test123",
products: ["313", "dasd", "dasfg"]
},
{
name: "test",
products: ["product", "product 2", "product 2", "product 3"]
}
],
count: 1,
productInputValues: {
name: "",
products: []
}
};
this.renderInputs = this.renderInputs.bind(this);
this.addInput = this.addInput.bind(this);
this.deleteRecipe = this.deleteRecipe.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleNameChange = this.handleNameChange.bind(this);
}
The function where the error comes from:
renderInputs() {
debugger;
let inputs = [];
for (let i = 0; i < this.state.count; i++) {
inputs.push(
<div key={i}>
<FormControl
type="text"
value={this.state.productInputValues.products[i] || ""}
onChange={this.handleChange.bind(this, i)}
placeholder={"Product " + (i + 1)}
/>
<Button onClick={this.removeInput.bind(this, i)}>Remove</Button>
</div>
);
}
return inputs || null;
}
My onChange input handlers:
handleChange(i, event) {
debugger;
let productInputValues = this.state.productInputValues.products;
productInputValues[i] = event.target.value;
this.setState({
productInputValues: {
products: productInputValues
}
});
}
handleNameChange(event) {
debugger;
this.setState({
productInputValues: {
name: event.target.value
}
});
}
and with this component, I'm creating the recipes:
class AddRecipe extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: false
};
this.close = this.close.bind(this);
this.open = this.open.bind(this);
}
close() {
this.setState({ showModal: false });
}
open() {
this.setState({ showModal: true });
}
render() {
return (
<div>
<Button bsStyle="primary" bsSize="large" onClick={this.open}>
Add Recipe
</Button>
<Modal show={this.state.showModal} onHide={this.close}>
<Modal.Header closeButton>
<Modal.Title>Add Recipe</Modal.Title>
</Modal.Header>
<form onSubmit={this.props.onSubmit}>
<Modal.Body>
<FormGroup controlId="RecipeName">
<ControlLabel>Recipe</ControlLabel>
<FormControl
type="text"
placeholder="Recipe Name"
onChange={this.props.handleNameChange}
/>
</FormGroup>
<FormGroup controlId="formControlsTextarea">
<ControlLabel>Products</ControlLabel>
{this.props.renderInputs()}
</FormGroup>
<Button onClick={this.props.addInput}>Add Product</Button>
</Modal.Body>
<Modal.Footer>
<Button bsStyle="success" type="submit">
Next station: Kitchen
</Button>
<Button onClick={this.close}>Close</Button>
</Modal.Footer>
</form>
</Modal>
</div>
);
}
}
Upvotes: 1
Views: 72
Reputation: 687
You are changing object productInputValues ..it does have products. In handleChange and handleNameChange use spread operator ..or copy object correctly.
handleChange(i, event) {
debugger;
let productInputValues =
this.state.productInputValues.products;
productInputValues[i] = event.target.value;
this.setState({
productInputValues: {...this.state.productInputValues,
products: productInputValues
}
});
}
handleNameChange(event) {
debugger;
this.setState({
productInputValues: {...this.state.productInputValues,
name : event.target.value
}
});
}
Upvotes: 2