Adding a list item via a button in React? - javascript

Here's the parts of my code that are useful:
class Answers extends Component {
constructor(props) {
super(props);
this.state = {
answers: Array(4).fill(""),
correctAnswers: [],
};
this.handleUpdate = this.handleUpdate.bind(this);
}
// let event = {
// index: 1,
// value: 'hello'
// };
handleUpdate (event) {
//if ("1" == 1) // true
//if ("1" === 1) //false
var answers = this.state.answers;
answers[event.index] = event.value;
this.setState(() => ({
answers: answers
}));
console.log(event);
}
render () {
return (
<div id="answers">
Answer Choices<br />
{this.state.answers.map((value, index) => (
<Answer value={value} key={index} onUpdate={this.handleUpdate} number={index}/>
))}
</div>
);
}
}
class Answer extends Component {
constructor(props) {
super(props);
this.state = {
inputText: "",
answer: props.value,
correctAnswers: "",
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
this.setState((previousState, props) => ({
answer: value
}));
this.props.onUpdate({
index: this.props.number,
value
});
//
// let sample = {
// kyle: "toast",
// cam: "pine"
// };
// sample.kyle
// sample.cam
}
render () {
return (
<div>
<input type="checkbox"/>
<input type="text" value={this.state.answer} onChange={this.handleChange}/>
</div>
)
}
}
var questionIdx = 0;
class Questions extends Component {
constructor(props){
super(props);
this.state = {
questions:[]
}
this.handleUpdate = this.handleUpdate.bind(this);
}
handleUpdate (event) {
//if ("1" == 1) // true
//if ("1" === 1) //false
var questions = this.state.questions
questions[event.index] = event.value;
this.setState(() => ({
questions: questions
}));
console.log(event);
}
render () {
return (
<div id="questions">
<ol id="quesitonsList">
<li id="oneQuestion">
<Question onUpdate={this.handleUpdate} number={questionIdx}/>
</li>
</ol>
</div>
);
}
}
class Question extends Component {
constructor(props){
super(props);
this.state = {
question: ""
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.type === "checkbox" ? target.checked : target.value;
const name = target.name;
this.setState((previousState, props) => ({
question: value
}));
//if (this.prop.questions.indexOf(value) == questionIdx) {
this.props.onUpdate({
index: questionIdx,
value
});
// }
}
render () {
return (
<div id="question">
Question<br />
<input type="text" value={this.state.question} onChange={this.handleChange}/>
<PhotoDropZone />
<Answers />
</div>
);
}
}
class AddQuestionButton extends Component {
addQuestion () {
}
render () {
return (
<div id="addQuestionButton">
<button id="addQuestionButton" onClick={this.addQuestion}>Add Question</button>
</div>
);
}
}
So what I am having trouble figuring out is how to go about using my addQuestionButton to add
<li id="oneQuestion">
<Question onUpdate={this.handleUpdate} number={questionIdx}/>
</li>
to my questionsList <ol></ol> in my Questions class. I'm having a hard time figuring out how to approach this, I'm new to React and JS. I don't need the exact answer per say but a hint in the right direction would help. Thanks!

You could create a function in your Questions that adds a question to your questions state array and pass that down as a prop to your AddQuestionButton component.
Example
class Questions extends React.Component {
state = {
questions: ["What is this?"]
};
addQuestion = question => {
this.setState(prevState => ({
questions: [...prevState.questions, question]
}));
};
render() {
return (
<div id="questions">
<ol id="quesitonsList">
{this.state.questions.map(question => (
<li id="oneQuestion"> {question} </li>
))}
</ol>
<AddQuestionButton onClick={this.addQuestion} />
</div>
);
}
}
class AddQuestionButton extends React.Component {
addQuestion = () => {
this.props.onClick(
Math.random()
.toString(36)
.substring(7) + "?"
);
};
render() {
return (
<div id="addQuestionButton">
<button id="addQuestionButton" onClick={this.addQuestion}>
Add Question
</button>
</div>
);
}
}
ReactDOM.render(<Questions />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Perhaps it may help you:
const questionsList = [1, 2, 3, 4, 5];
const listItems = questionsList.map((item, index) =>(
<li key="{index}">
<Question onUpdate={this.handleUpdate} number={questionIdx}/>
</li>
));
ReactDOM.render(
<ol>{listItems}</ol>
);

Related

how to display data on click react

Implemented writing data from the form to the array. Everything works. but now I want to implement data output when I click on " SEND ARR "
When I hang up a click on a button, respectively, the data is not displayed since in the function we access event.target.value
Please tell me how to rewrite the line so that I can display data when I click on the button? thank
home.js
import React from "react";
import "./../App.css"
export default class Home extends React.Component {
constructor() {
super()
this.state = {
count: 1,
objexm: '',
inputValue: '',
arr: []
}
this.handleClick = this.handleClick.bind(this);
this.updateInputValue = this.updateInputValue.bind(this);
}
handleClick() {
this.setState({
count: this.state.count + 1
});
};
createMarkup() {
return {
__html: this.state.inputValue
};
};
updateInputValue(event) {
let newArr = this.state.arr;
let newlist = event.target.value;
if (event.target.value) {
newArr.push(newlist)
}
this.setState({
inputValue: newArr
});
event.target.value = '';
};
render() {
return (
<div className="home-header">
<h2>{this.state.count}</h2>
<button onClick={this.handleClick}>Add</button>
<input type='text' name="names" onClick={this.updateInputValue} />
{this.state.arr.map((arrs, index) => {
return (
<li
key={index}
>{arrs}</li>
)
})}
<button>SEND ARR</button>
<ul className="qwe">
<li dangerouslySetInnerHTML={this.createMarkup()}></li>
</ul>
</div>
);
}
}
Store the data from the input into invputValue each time the input is updated and on the click of the button update the arr content with the old values (...arr) plus the current input value (this.state.inputValue) .
To make sure the old values are not deleted the arr is defined at the top of the class let arr = []. If you don't want it there you can instantiate it in the constructer which will run only once. i.e. this.arr = []
let arr = []
class Home extends React.Component {
constructor() {
super()
this.state = {
count: 1,
objexm: '',
inputValue: '',
arr: []
}
this.handleClick = this.handleClick.bind(this);
this.updateInputValue = this.updateInputValue.bind(this);
}
handleClick() {
this.setState({
count: this.state.count + 1
});
};
createMarkup() {
return {
__html: this.state.inputValue
};
};
updateInputValue = e => {
this.setState({ inputValue: e.target.value })
}
displayData = () => {
arr = [...arr ,this.state.inputValue]
this.setState({ arr, inputValue: "" })
}
clearData = () => {
this.setState({ arr: [] })
}
render() {
console.log("this.state.arr:", this.state.arr)
return (
<div className="home-header">
<h2>{this.state.count}</h2>
<button onClick={this.handleClick}>Add</button>
<input type='text' name="names" onChange={this.updateInputValue} value={this.state.inputValue} />
{this.state.arr.map((arrs, index) => {
return (
<li
key={index}
>{arrs}</li>
)
})}
<button onClick={this.displayData}>SEND ARR</button>
<button onClick={this.clearData}>CLEAR ARR</button>
<ul className="qwe">
<li dangerouslySetInnerHTML={this.createMarkup()}></li>
</ul>
</div>
);
}
}
Instead of using onClick on input, use onChange and update value in state i.e. make the input a controlled component . Post that onClick of button take the value from state and push to the array and clear the input value
export default class Home extends React.Component {
constructor() {
super()
this.state = {
count: 1,
objexm: '',
inputValue: '',
arr: []
}
this.handleClick = this.handleClick.bind(this);
this.updateInputValue = this.updateInputValue.bind(this);
}
handleClick() {
this.setState(prevState => ({
count: prevState.count + 1,
inputValue: [...prevState.inputValue, prevState.name],
name: ""
}));
};
createMarkup() {
return {
__html: this.state.inputValue
};
};
updateInputValue(event) {
let newVal = event.target.value;
this.setState({
name: newVal
});
};
render() {
return (
<div className="home-header">
<h2>{this.state.count}</h2>
<button onClick={this.handleClick}>Add</button>
<input type='text' name="names" value={this.state.name} onChange={this.updateInputValue} />
{this.state.arr.map((arrs, index) => {
return (
<li
key={index}
>{arrs}</li>
)
})}
<button>SEND ARR</button>
<ul className="qwe">
<li dangerouslySetInnerHTML={this.createMarkup()}></li>
</ul>
</div>
);
}
}

Changing state of child component from parent with refs

I have a TaskList. I'm trying to display a child component TaskEdit (edit box for the task) several components lower, onClick of a button.
TaskEdit has a state variable hidden, set to true by default. How do I change the state inside the child component from within the child component?
React documentation mentions a forwardRef() function in order to reference the child component, but I haven't any luck so far with it.
Here's my code:
import TaskEdit from '../TaskEdit';
class TasksBase extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
tasks: [],
};
this.markTaskAsCompleted = this.markTaskAsCompleted.bind(this);
this.deleteTask = this.deleteTask.bind(this);
this.incrementDate = this.incrementDate.bind(this);
this.toggleTaskEdit = this.toggleTaskEdit.bind(this);
}
componentDidMount() {
this.onListenForTasks();
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
const { tasks, loading } = this.state;
return (
<div>
{loading && <div>Loading ...</div>}
{tasks ? (
<TaskList tasks={tasks}
handleToggleEdit={this.toggleTaskEdit}
handleMarkCompleted={this.markTaskAsCompleted}
handleDeleteTask={this.deleteTask}
taskEditElement={this.editTaskElement}
/>
):(
<div>There are no tasks ...</div>
)}
</div>
);
}
onListenForTasks() {
this.setState({ loading: true });
this.unsubscribe = this.props.firebase
.tasks()
.orderBy('importance', 'desc')
.orderBy('urgency', 'desc')
.orderBy('created', 'desc')
.onSnapshot(snapshot => {
if (snapshot.size) {
let tasks = [];
snapshot.forEach(doc =>
tasks.push({ ...doc.data(), uid: doc.id }),
);
this.setState({
tasks: tasks,
loading: false
});
} else {
this.setState({ tasks: null, loading: false });
}
});
}
markTaskAsCompleted(task){
// Some code
}
deleteTask(id){
// Some code
}
toggleEditTask(){
this.editTaskElement.current.toggle();
}
}
const Tasks = withFirebase(TasksBase);
const TaskList = ({ tasks, handleToggleEdit, handleMarkCompleted, handleDeleteTask }) => (
<ul className="tasks">
{tasks.map( task => (
<Task key={task.uid}
task={task}
handleToggleEdit={handleToggleEdit}
handleMarkCompleted={handleMarkCompleted}
handleDeleteTask={handleDeleteTask}
/>
))}
</ul>
);
const Task = ({ task, handleToggleEdit, handleMarkCompleted, handleDeleteTask}) => (
(!task.completed && !task.obsolete && !task.waitingForDependencies) && (!task.start || task.start.toMillis() <= Date.now()) &&
<li className="task">
<strong>{task.userId}</strong> {task.name}
{ task.estimate &&
<span>{task.estimate.amount + task.estimate.unit}</span>
}
<div className="icons">
<FontAwesomeIcon icon="edit" onClick={() => handleToggleEdit(task)} />
<FontAwesomeIcon icon="check-circle" onClick={() => handleMarkCompleted(task)} />
<FontAwesomeIcon icon="times-circle" onClick={() => handleDeleteTask(task.uid)}/>
</div>
<TaskEdit task={task} />
</li>
);
const condition = authUser => !!authUser;
export default compose(
withEmailVerification,
withAuthorization(condition),
)(Tasks);
TaskEdit:
import React, { Component } from 'react';
import { withFirebase } from '../Firebase';
const INITIAL_STATE = {
hidden: true,
};
class TaskEditBase extends Component {
constructor(props) {
super(props);
this.state = { ...INITIAL_STATE };
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log("name " + name);
console.log("value " + value);
this.setState({
[name]: value
});
}
toggle(){
this.setState({
hidden: !this.prevState.hidden
})
}
onSumbitTaskEdit = (event) => {
event.preventDefault();
};
render(){
return(
!this.state.hidden &&
<div className="task-edit">
<form onSubmit={this.onSumbitTaskEdit}>
<div>A bunch of inputs</div>
<input type="submit" value="Edit"/>
</form>
</div>
)
}
}
const TaskEdit = withFirebase(TaskEditBase);
export default TaskEdit;

handleRemove function for Todo List app with an array of objects

So I am making this app super simple, however I can't get my handleRemove to work properly. filteredTodos comes out to be a list of all the same todos. This is my code.
I have tried even looking at other solutions online but for some reason this filter function in handleRemove does not filter anything out of the state.
import React, { Component } from 'react';
class Main extends Component {
constructor(props){
super(props);
this.state = {
todos: [],
inputValue: '',
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleRemove = this.handleRemove.bind(this);
}
handleChange = (e) => {
e.preventDefault();
this.setState({
inputValue: e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
const newTodo = this.state.inputValue;
if (this.state.inputValue === ''){
alert('Please Enter a Todo!');
} else {
this.setState((prevState) => ({
todos: [...prevState.todos,
{
message: newTodo,
id: this.state.todos.length
}
]
}));
this.setState({inputValue:''});
}
}
handleRemove (id) {
const filteredTodos = this.state.todos.filter(todo => todo.id !== id);
this.setState({
todos: filteredTodos
});
console.log(filteredTodos);
}
render(){
const mappedTodos = this.state.todos.map((item, i) =>
<div key={i} id={this.state.todos[i].id}>
{item.message} <button type='submit' onClick={this.handleRemove}>X</button>
</div>
)
return(
<div className='main-page'>
<div className='input'>
<input type='text' placeholder='Enter Your Todo' value={this.state.inputValue} onChange={this.handleChange} />
<button type='submit' onClick={this.handleSubmit}>Add</button>
</div>
<div className='todos'>
{mappedTodos}
</div>
</div>
)
}
}
export default Main;
Your handleRemove function requires an id you can see it by the value in the round brackets
handleRemove (id)
to fix the problem you just have to pass the parameter just like this:
const mappedTodos = this.state.todos.map((item, i) =>
<div key={i} id={this.state.todos[i].id}>
{item.message} <button type='submit' onClick={this.handleRemove(this.state.todos[i].id)}>X</button>
</div>
)

unable to perform dynamic search in react app using static data

I am performing sort , filter and pagination on my react app which displays data from a json file which includes movies data. I am able to fetch data from input box but unable to setState and also console log searchKey and movies.
Below is the code for App.js and Hello.js. App component has both sort and search functions.
App.js
import data from './data.json';
class App extends Component {
constructor() {
super();
this.state = {
movies: data.movies, sort_term: '', searchKey: '', filterList: '',
};
this.onSorting = this.onSorting.bind(this);
this.onSearchMovie = this.onSearchMovie.bind(this);
}
onSorting = (e) => {
let term = 'Title';
let option = e.target.value;
let sortedList = [...this.state.movies].sort((a, b) => {
return (option == 'asc' ? (a[term] <= b[term] ? -1 : 1) :
(a[term] >= b[term] ? -1 : 1))
});
this.setState({ sort_term: term });
this.setState({ movies: sortedList });
}
onSearchMovie(e) {
let key = e;
console.log(key);
this.setState({searchKey : key });
console.log(searchKey);
let list = movies.filter(m =>{
return m.Title.toLowerCase().includes(searchKey.toLowerCase());
});
this.setState({movies:list});
}
render() {
const { movies } = this.state;
if (!movies.length) {
return (
<div className="container">
<h2>loading...</h2>
</div>
);
}
else {
return (
<div>
<Hello sort_term={this.state.sort_term}
onSorting={this.onSorting}
onSearch={this.onSearchMovie} />
<br />
<Table movies={this.state.movies} />
</div>
);
}
}
}
Hello.js
class Hello extends Component {
constructor(props) {
super(props);
this.state = { inputField: '', }
this.onSubmitTitle = this.onSubmitTitle.bind(this);
this.getTitle = this.getTitle.bind(this);
}
onSubmitTitle(e){
e.preventDefault();
this.props.onSearch(this.state.inputField);
this.setState({ inputField: '' });
}
getTitle(e){
this.setState({ inputField: e.target.value });
// console.log('---');
// console.log(this.state.inputField);
}
render() {
const { sort_term, onSorting } = this.props;
return (
<div className="header">
Database
<ul className="navLeft">
<li>
<form onSubmit={this.onSubmitTitle}>
<input type="search" onChange={this.getTitle} value={this.state.inputField}
className="search-bar"
placeholder="Type for search..." />
</form>
</li>
<li >
<form >
<select
onChange={onSorting}
className="searchBar">
<option value="desc" >Sort Title(Z - A)</option>
<option value="asc">Sort Title(A - Z)</option>
<option value="descDirector">Sort Director(Z - A)</option>
<option value="ascDirector">Sort Director(A - Z)</option>
</select>
</form>
</li>
</ul>
</div>
);
}
}
You got couple of issues:
You got some undefined variables here:
onSearchMovie(e) {
let key = e;
console.log(key);
this.setState({ searchKey: key });
console.log(searchKey);
let list = movies.filter(m => {
return m.Title.toLowerCase().includes(searchKey.toLowerCase());
});
this.setState({ movies: list });
}
like `searchKey` and `movies`.
setState is asynchronous, so doing this:
this.setState({ sort_term: term });
this.setState({ movies: sortedList });
Is the same as doing this:
this.setState({
sort_term: term,
movies: sortedList
});
With that saying, this code block may not work as expected:
onSearchMovie(e) {
let key = e;
console.log(key);
this.setState({ searchKey: key });
console.log(searchKey);
let list = movies.filter(m => {
return m.Title.toLowerCase().includes(searchKey.toLowerCase());
});
this.setState({ movies: list });
}
Because as mentioned above, setState is asynchronous. so this.state.searchKey may not be what you think when you access it the next line.
Either use the key variable or use the setState callback which will trigger after setState has done.
this.setState({someKey: someValue}, () => {console.log(this.state.someKey)})
You can read more about it in the docs Why is setState giving me the
wrong value?.
Another thing you may not know is that when you use onSubmit on a
form you actually need to trigger the submit. Since you don't have
any submit button you can do it with the enter key. so while you
are focused on the input press the enter key and the form will
get submitted.
Another thing i would do, is to display and update a filteredMovis
list instead of the movies list directly because once you filter
out items then you can't get them back. so when you do filtering you
do it on movies but updating the filteredMovis list without
removing items from the original movies list.
Here is a working and running example:
const data = {
movies: [
{
id: 1,
Title: "wonder woman"
},
{
id: 2,
Title: "kill bill"
},
{
id: 3,
Title: "world war z"
},
{
id: 4,
Title: "pixels"
}
]
};
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { inputField: "" };
this.onSubmitTitle = this.onSubmitTitle.bind(this);
this.getTitle = this.getTitle.bind(this);
}
onSubmitTitle(e) {
e.preventDefault();
this.props.onSearch(this.state.inputField);
this.setState({ inputField: "" });
}
getTitle(e) {
this.setState({ inputField: e.target.value });
// console.log('---');
// console.log(this.state.inputField);
}
render() {
const { onSorting } = this.props;
return (
<div className="header">
Database
<ul className="navLeft">
<li>
<form onSubmit={this.onSubmitTitle}>
<input
type="text"
onChange={this.getTitle}
value={this.state.inputField}
className="search-bar"
placeholder="Type for search..."
/>
</form>
</li>
<li>
<form>
<select onChange={onSorting} className="searchBar">
<option value="desc">Sort Title(Z - A)</option>
<option value="asc">Sort Title(A - Z)</option>
<option value="descDirector">Sort Director(Z - A)</option>
<option value="ascDirector">Sort Director(A - Z)</option>
</select>
</form>
</li>
</ul>
</div>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
movies: data.movies,
filteredMovis: data.movies,
sort_term: "",
searchKey: "",
filterList: ""
};
this.onSorting = this.onSorting.bind(this);
this.onSearchMovie = this.onSearchMovie.bind(this);
}
onSorting = e => {
let term = "Title";
let option = e.target.value;
let sortedList = [...this.state.movies].sort((a, b) => {
return option == "asc"
? a[term] <= b[term]
? -1
: 1
: a[term] >= b[term]
? -1
: 1;
});
this.setState({
sort_term: term,
filteredMovis: sortedList
});
};
onSearchMovie(key) {
const { movies } = this.state;
let list = movies.filter(m => {
return m.Title.toLowerCase().includes(key.toLowerCase());
});
this.setState({ filteredMovis: list, searchKey: key });
}
render() {
const { filteredMovis, movies } = this.state;
if (!movies.length) {
return (
<div className="container">
<h2>loading...</h2>
</div>
);
} else {
return (
<div>
<Hello
sort_term={this.state.sort_term}
onSorting={this.onSorting}
onSearch={this.onSearchMovie}
/>
<br />
{filteredMovis.map(movie => <div key={movie.id}>{movie.Title}</div>)}
</div>
);
}
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Lifting shared State up the tree

I'm trying to build a little React app that when a user selects a meat product the ui will show that category of meat from the json data file. I have a Products class as the parent to a class ProductCategoryRow and a SelectProduct function. I'm a little confused as to how to set the state in the Products class and pass the props on to ProductCategoryRow and SelectProduct.
function SelectProduct (props) {
const products = ['All', 'Beef', 'Lamb', 'Poultry'];
return (
<ul className='products'>
{products.map(function (prod) {
return (
<li
style={prod === props.selectedProduct ? { color: '#d0021b' }:null}
onClick={props.onSelect.bind(null, prod)}
key={prod}>
{prod}
</li>
)
})}
</ul>
)};
class ProductCategoryRow extends React.Component {
constructor(props) {
super(props);
this.state = {
list: list,
};
this.onDismiss = this.onDismiss.bind(this);
}
onDismiss(id) {
const isNotId = item => item.objectID !== id;
const updatedList = this.state.list.filter(isNotId);
this.setState({ list: updatedList });
}
render() {
return (
<div className="container">
{ this.state.list.map(item =>
<div key={item.objectID} className="product-category-row">
<div>{item.category}</div>
<div>{item.meatCut}</div>
<div>{item.cooking}</div>
<div>{item.price}</div>
<div>
<button
onClick={() => this.onDismiss(item.objectID)}
type="button"
>
Dismiss
</button>
</div>
</div>
)}
</div>
)
}
}
SelectProduct.propTypes = {
selectedProduct: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired,
}
class Products extends React.Component {
constructor (props) {
super(props);
this.state = {
selectedProduct: 'All',
lists: null
};
this.updateProduct = this.updateProduct.bind(this);
}
componentDidMount () {
this.updateProduct(this.state.selectedProduct);
}
updateProduct(prod) {
this.setState(function () {
return {
selectedProduct: prod,
lists: null
}
})
}
render() {
return (
<div>
<SelectProduct
selectedProduct={this.state.selectedProduct}
onSelect={this.updateProduct}
/>
<ProductCategoryRow />
</div>
)
}
}
export default Products;
Thanks in advance
You are already updating your parent component state when a product is selected, so that is good! Now, you need to pass in this.state.selectedProduct to the ProductCategoryRow component as a selectedProduct prop in your render method:
function SelectProduct (props) {
const products = ['All', 'Beef', 'Lamb', 'Poultry'];
return (
<ul className='products'>
{products.map(function (prod) {
return (
<li
style={prod === props.selectedProduct ? { color: '#d0021b' }:null}
onClick={props.onSelect.bind(null, prod)}
key={prod}>
{prod}
</li>
)
})}
</ul>
)};
class ProductCategoryRow extends React.Component {
constructor(props) {
super(props);
this.state = {
list: list,
};
this.onDismiss = this.onDismiss.bind(this);
}
onDismiss(id) {
const isNotId = item => item.objectID !== id;
const updatedList = this.state.list.filter(isNotId);
this.setState({ list: updatedList });
}
render() {
return (
<div className="container">
{ this.state.list.map(item =>
<div key={item.objectID} className="product-category-row">
<div>{item.category}</div>
<div>{item.meatCut}</div>
<div>{item.cooking}</div>
<div>{item.price}</div>
<div>
<button
onClick={() => this.onDismiss(item.objectID)}
type="button"
>
Dismiss
</button>
</div>
</div>
)}
</div>
)
}
}
SelectProduct.propTypes = {
selectedProduct: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired,
}
class Products extends React.Component {
constructor (props) {
super(props);
this.state = {
selectedProduct: 'All',
lists: null
};
this.updateProduct = this.updateProduct.bind(this);
}
componentDidMount () {
this.updateProduct(this.state.selectedProduct);
}
updateProduct(prod) {
this.setState(function () {
return {
selectedProduct: prod,
lists: null
}
})
}
render() {
return (
<div>
<SelectProduct
selectedProduct={this.state.selectedProduct}
onSelect={this.updateProduct}
/>
<ProductCategoryRow selectedProduct={this.state.selectedProduct} />
</div>
)
}
}
export default Products;

Categories