I made a recipe box with ReactJS. Please let me know what room for improvement you see. I did notice that with codepen, the list of components started to become lengthy to look at. Is it a best practice to separate the different components into different js files? Here is the codepen: https://codepen.io/capozzic1/pen/gmpVyr. Here is the code: var Grid = ReactBootstrap.Grid; var Col = ReactBootstrap.Col; var Row = ReactBootstrap.Row; /* Component ideas -recipeCon -RecipeList -Recipe ingredients -edit-delete -addRecipe button -recipe entry */ var recipes = [{ title: "Pizza", ingredients: ["Tomato Sauce", "Yeast"] }, { title: "Cookies", ingredients: ["Cookie Dough", "Chocolate chips"] }, { title: "Turkey tacos", ingredients: ["Nacho cheese taco shells", "Turkey"] } ] //holds all other components. has add/edit methods class RecipeContainer extends React.Component { constructor(props) { super(props); this.state = ({ recipes: recipes, edit: false, editTitle: "", editIngred: "", }); this.addRecipe = this.addRecipe.bind(this); this.editRecipe = this.editRecipe.bind(this); this.addBtnEdit = this.addBtnEdit.bind(this); this.editText = this.editText.bind(this); this.editContents = this.editContents.bind(this); this.handleOpen = this.handleOpen.bind(this); } editRecipe() { this.setState({ edit: true }); } editText(editTitle, editIngred) { this.setState({ editTitle: editTitle, editIngred: editIngred }) } addRecipe(recipe) { recipes.push(recipe); this.setState({ recipes: recipes }); } addBtnEdit() { this.setState({ edit: false }); } editContents() { this.setState({ recipes: recipes }); console.log(recipes); } handleOpen() { document.querySelector(".recEntry").style.visibility = 'visible'; } render() { return ( <Grid> <Row className="show-grid"> <Col md={12}> <div className="recipeCon"> <h2 className="text-center mainh2">A recipe box</h2> <RecipeList recipes={this.state.recipes} edit={this.editRecipe} editText={this.editText} deleteContents={this.editContents} open={this.handleOpen}/> <AddRecipeBtn editTrue={this.addBtnEdit} open={this.handleOpen}/> </div> <div className="recEntryWrap"> <RecipeEntry addRecipe={this.addRecipe} editStat={this.state.edit} editTitle={this.state.editTitle} editIngred={this.state.editIngred} editCont={this.editContents}/> </div> </Col> </Row> </Grid> ); } } //show list of recipe names class RecipeList extends React.Component { constructor(props) { super(props); this.handleEdit = this.handleEdit.bind(this); this.handleDelete = this.handleDelete.bind(this); this.handleToggle = this.handleToggle.bind(this); } handleEdit(e) { this.props.edit(); var editTitle = $(e.target).siblings("h2").text(); var editIngred = $(e.target).siblings("li").map(function(i, listi) { return $(listi).text(); }).toArray().join(','); this.props.editText(editTitle, editIngred); //document.appendChild(test); //value={editStat ? editTitle : ""} $('.titleSpan').text(editTitle); $('.inpIngred').val(editIngred); this.props.open(); } handleDelete(e) { var recTitle = $(e.target).siblings("h2").text(); for (var i = 0; i < recipes.length; i++) { if (recTitle === recipes[i].title) { recipes.splice(i, 1); } } this.props.deleteContents(); } handleToggle(e) { var sib = $(e.target).siblings().toggle(); console.log(sib); } //onclick of edit, get title and ingredients render() { //generate list of li items and add to ul var recipes = this.props.recipes; var recLi = recipes.map((recipe, index) => <div key={index}> <h2 className="rech2" onClick={this.handleToggle}>{recipe.title}</h2> { recipe.ingredients.map((ingred,index) =><li key={index + "id"}> {ingred}</li>) } <button onClick={this.handleEdit} className="editBtn">Edit</button> <button onClick={this.handleDelete} className="deleteBtn">Delete</button> </div> ); return ( <div className="recList"> <ul className="recUl"> {recLi} </ul> </div> ); } } //recipe button for showing recipe entry div class AddRecipeBtn extends React.Component { constructor(props) { super(props); this.showEntry = this.showEntry.bind(this); } showEntry() { this.props.open(); this.props.editTrue(); //empty the inputs and spans whenever add new recipe is clicked $(".inpIngred").val(""); $(".inpName").val(""); $(".titleSpan").text(""); } render() { return ( <button onClick={this.showEntry} className="bigAdd">Add New Recipe</button> ); } } //enter a new recipe, also handles edit of recipes class RecipeEntry extends React.Component { constructor(props) { super(props); this.handleAdd = this.handleAdd.bind(this); this.handleEdit = this.handleEdit.bind(this); this.handleClose = this.handleClose.bind(this); } handleAdd() { var titleVal = document.querySelector(".inpName").value; var ingVal = document.querySelector(".inpIngred").value; var newRecipe; var ingArr = ingVal.split(","); for (var i = 0; i <= recipes.length; i++) { if (recipes.length >= 0) { newRecipe = { title: titleVal, ingredients: ingArr }; this.props.addRecipe(newRecipe); this.handleClose(); break; } else if (titleVal === recipes[i].title) { alert("This recipe already exists"); break; } } } handleClose() { var recEntry = document.querySelector(".recEntry"); recEntry.style.visibility = "hidden"; } handleEdit() { var titleVal = document.querySelector(".titleSpan").textContent; var ingVal = document.querySelector(".inpIngred").value; var ingArr = ingVal.split(","); console.log(titleVal); //update specific object for recipes array for (var i = 0; i < recipes.length; i++) { if (recipes[i].title == titleVal) { var newTitle = document.querySelector(".inpName").value; recipes[i].title = newTitle; recipes[i].ingredients = ingArr; } } console.log(recipes); //let the recipe container know to update the state this.props.editCont(); this.handleClose(); } render() { var editStat = this.props.editStat; var editTitle = this.props.editTitle; var editIng = this.props.editIngred; return ( <div className="recEntry"> <h2>{editStat ? 'Edit a recipe' : 'Add a recipe'}</h2> <h3>Title</h3> <p><b>{editStat ? 'Old title: ' : ""}</b><span className="titleSpan"></span></p> <input type="text" className="inpName" /> <h3>Ingredients</h3> <p className="instruct">Please put commas(",") in between ingredient names.</p> <textarea className="inpIngred" /> <button onClick={editStat ? this.handleEdit : this.handleAdd} className="saveBtn">{editStat ? 'Save' : 'Add recipe'}</button> <button onClick={this.handleClose} className="closeBtn">Close</button> </div> ); } } ReactDOM.render(<RecipeContainer/>, document.querySelector(".recWrap")); /*$(".rech2").on('click',function(){ console.log("test"); });*/