When I add a new recipe it gets saved into localStorage just fine, but my SideBarItem component doesn’t update immediately after saving. It only updates after clicking either the Add Recipe button or (if the list is populated) one of the list items. I think what is happening is that the Main component is not updating after submitting the form, therefore the child components don’t update.
Main.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Content from "./components/content.js";
import Sidebar from "./components/sidebar.js";
import SidebarItem from "./components/sidebarItem.js";
import AddItem from "./components/addItem.js";
import AddModal from "./components/addModal.js";
import "./styles.css";
/*
get KEY for recipes
http://api2.bigoven.com/web/console?x=1&reload=true
http://forum.freecodecamp.org/t/react-js-getting-a-separate-component-to-re-render/40911
https://stackoverflow.com/questions/39752287/react-js-getting-a-separate-component-to-re-render-when-localstorage-state-is
*/
class Main extends Component {
constructor(props) {
super(props);
this.state = {
currentRecipe: null,
addModal: false,
childData: "",
added: false
};
}
displayRecipe = (recipeInfo, id) => {
this.recipeContent = (
<div>
<div>Name: {recipeInfo.name}</div>
<div>Ingredients: {recipeInfo.ingredients}</div>
</div>
);
this.setState({
currentRecipe: this.recipeContent
});
};
addRecipeDisplay = () => {
this.setState(
{
addModal: true
},
() => {
// console.log(this.state); // Mustkeom
}
);
};
saveNewRecipe = dataFromChild => {
this.setState(
{
childData: dataFromChild,
recipeId: (Math.random() * 100).toFixed(3),
addModal: false,
added: true
},
() => {
localStorage.setItem(
`recipe-${this.state.recipeId}`,
JSON.stringify(this.state.childData)
);
}
);
};
render() {
return (
<div className="main">
<h1>Recipe Box</h1>
<h2>Check out some recipes or add your own!</h2>
<AddItem addNewRecipe={e => this.addRecipeDisplay(e)} />
<Sidebar>
<SidebarItem
sidebarItemClicked={this.displayRecipe}
recipeAdded={this.state.added}
/>
</Sidebar>
<Content recipe={this.state.currentRecipe} />
{this.state.addModal && <AddModal saveRecipe={this.saveNewRecipe} />}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Main />, rootElement);
/*
Components
RecipeBox: parent component
RecipeList: index of already created recipes
Recipe: a single recipe -- can create, edit, save, and delete
*/
SidebarItem.js
import React, { Component } from "react";
class SidebarItem extends Component {
constructor(props) {
super(props);
this.state = {
recipeArray: []
};
}
renderListItems = () => {
return Object.keys(localStorage).map((r, i) => {
if (r.split("").includes("-")) {
let recipeInfo = JSON.parse(localStorage[r]);
return (
<li key={recipeInfo.recipeId}>
<button onClick={() => this.sendBackRecipeId(recipeInfo, r)}>
{recipeInfo.name}
</button>
</li>
);
}
});
};
sendBackRecipeId(r, id) {
this.props.sidebarItemClicked(r, id);
}
render() {
return <div>{this.renderListItems()}</div>;
}
}
export default SidebarItem;
AddModal.js
import React, { Component } from "react";
class AddModal extends Component {
constructor(props) {
super(props);
this.state = {
nameValue: "",
ingredientValue: ""
};
this.sendBackData = this.sendBackData.bind(this);
}
sendBackData = evt => {
evt.preventDefault();
this.props.saveRecipe({
name: this.state.nameValue,
ingredients: this.state.ingredientValue
});
};
handleNameChange = event => {
this.setState({ nameValue: event.target.value });
};
handleIngredientsChange = event => {
this.setState({ ingredientValue: event.target.value });
};
render() {
return (
<div>
<h3>Add New Recipe</h3>
<form onSubmit={this.sendBackData}>
<input
type="text"
placeholder="recipe name"
value={this.state.nameValue}
onChange={this.handleNameChange}
/>
<input
type="text"
placeholder="recipe ingredients"
value={this.state.ingredientValue}
onChange={this.handleIngredientsChange}
/>
<input type="submit" defaultValue="save" />
</form>
</div>
);
}
}
export default AddModal;
Sidebar.js
import React, { Component } from "react";
// import SidebarItem from "./sidebarItem.js";
class Sidebar extends Component {
componentDidUpdate() {
// console.log(this);
}
render() {
return (
<div>
<ul className="sidebar">
<h3>Sidebar</h3>
{this.props.children}
</ul>
</div>
);
}
}
export default Sidebar;