Reputation: 39
my question is about React add and edit items.I want to add object in array (object which contain amount, amountUnit, name in array) console.log is OK but object wasn´t added. On my Form a cannot show result of this function. I want to add new object of list of ingredietns from API. I dont know if i have bad props or states
import React, { Component } from "react";
import {
FormGroup,
FormControl,
ControlLabel,
InputGroup
} from "react-bootstrap";
export default class AddIngredient extends Component {
constructor(props) {
super(props);
this.state = {
ingredients: [],
amount: " ",
amountUnit: " ",
name: " "
};
}
onChangeAmount = e => {
this.setState({ amount: e.target.value });
console.log("amount was changed");
};
onChangeAmountUnit = e => {
this.setState({ amountUnit: e.target.value });
console.log("amount unit was changed");
};
onChangeName = e => {
this.setState({ name: e.target.value });
console.log("name was changed");
};
onClickAddIngredient = e => {
const { amount, amountUnit, name } = this.state;
const newIngredient = { amount, amountUnit, name };
this.setState({ ingredients: [...this.state.ingredients, newIngredient] });
console.log("was added");
};
render() {
const { amount, amountUnit, name } = this.props;
return (
<React.Fragment>
<FormGroup>
<ControlLabel>Přidat ingredienci</ControlLabel>
<InputGroup className="frow">
<FormControl
type="number"
placeholder="Množství"
min="0"
value={amount}
onChange={this.onChangeAmount}
/>
<FormControl
type="text"
placeholder="Jednotka"
value={amountUnit}
onChange={this.onChangeAmountUnit}
/>
</InputGroup>
<InputGroup>
<FormControl
type="text"
placeholder="Název"
value={name}
onChange={this.onChangeName}
/>
<InputGroup.Addon>
<button onClick={this.onClickAddIngredient} className={"addon"}>
Přidat
</button>
</InputGroup.Addon>
</InputGroup>
</FormGroup>
</React.Fragment>
);
}
}
<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>
import React, { Component } from "react";
import IngredientItems from "./IngredientItems";
import AddIngredient from "./AddIngredient";
import Directions from "./Directions";
import { FormGroup, Button, ButtonGroup, Grid } from "react-bootstrap";
import BasicInfo from "./BasicInfo";
export default class RecipeForm extends Component {
constructor(props) {
super(props);
this.state = {
title: props.title || "",
servingCount: props.servingCount,
preparationTime: props.preparationTime,
sideDish: props.sideDish,
directions: props.directions,
ingredients: props.ingredients
};
}
onChange = (key, value) => {
this.setState({ [key]: value });
};
render() {
const { onCancel } = this.props;
const {
ingredients,
title,
servingCount,
sideDish,
preparationTime,
directions
} = this.state;
return (
<Grid>
<ButtonGroup
className="pull-right"
size="lg"
aria-label="Basic example"
>
<Button onClick={this.onSave} bsStyle="success">
Uložit
</Button>
<Button onClick={onCancel} bsStyle="default">
Zrušit
</Button>
</ButtonGroup>
<BasicInfo
title={title}
preparationTime={preparationTime}
servingCount={servingCount}
sideDish={sideDish}
onChange={this.onChange}
/>
<IngredientItems ingredients={ingredients} />
<Directions directions={directions} onChange={this.onChange} />
<AddIngredient onChange={this.onChange} />
<FormGroup />
</Grid>
);
}
}
<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>
Upvotes: 2
Views: 985
Reputation: 33544
You have local state ingredients
in your AddIngredient
component, but it is never actually rendered.
It looks like what you want to do is pass a handler to that component, which updates the ingredient
array in the parent component.
AddIngredient.js
onClickAddIngredient = e => {
const { amount, amountUnit, name } = this.state;
const newIngredient = { amount, amountUnit, name };
// call handler from parent and update there
this.props.onAdd(newIngredient);
console.log("was added");
};
RecipeForm.js
onAddIngredient = (newIngredient) => {
this.setState({ ingredients: [...this.state.ingredients, newIngredient] });
};
Also it looks like you don't need to pass the onChange
down to this component, since the input fields are just being held in it's local state. So you can just render it like this with the new handler added:
<AddIngredient onAdd={this.onAddIngredient} />
Then you can remove the local state ingredients
in the subcomponent since it's not being used.
Upvotes: 1