error while using state and map in reactjs - reactjs

I am new to react. I am fetching github user info on search. I unable
to fetch data in my child component. this is my code below.
whats the problem , cant i use this.state.userList.map
class SearchHeader extends Component {
constructor(props) {
super(props);
this.state = {
errorMessage: '',
userList: [],
isOpen: false,
userName:''
};
this.toggle = this.toggle.bind(this);
this.getUsers = this.getUsers.bind(this);
}
toggle() {
this.setState({
isOpen: !this.state.isOpen
});
}
// componentWillMount(){
// this.getUsers();
// }
getUsers(e) {
console.log('get users called='+e.target.value);
fetch('https://api.github.com/search/users?q='+ e.target.value)
.then(res => res.json())
.then(
userList =>{
this.setState({userList: userList})
console.log(userList);
}
);
}
render() {
return (
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-primary navbar-inner">
<div className="collapse navbar-collapse navbar-inner navb" >
<ul className="navbar-nav bg-light mr-auto">
<li className="nav-item dropdown">
<a className="nav-link dropdown-toggle auto" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sort
</a>
<div className="dropdown-menu" aria-labelledby="navbarDropdown">
<a className="dropdown-item" href="#">Sort by Name (ascending)</a>
<a className="dropdown-item" href="#">Sort by Name (descending)</a>
<div className="dropdown-divider"></div>
<a className="dropdown-item" href="#">Sort by Rank (ascending)</a>
<a className="dropdown-item" href="#">Sort by Rank (descending)</a>
</div>
</li>
</ul>
<form className="form-inline my-2 my-lg-0 auto" onSubmit={this.getUsers}>
<div className="form-group">
<input className="form-control mr-sm-2" type="Search" placeholder="Search"
aria-label="Search"
id="userName"
onKeyUp={this.getUsers} >
</input>
</div>
</form>
</div>
</nav>
<div >
<UserList userList={this.state.userList}/>
</div>
</div>
);
}
}
export default SearchHeader;
This is my child component below where I am fetching data from parent
component
This is my child component below where I am fetching data from parent
component
class UserList extends Component {
constructor(props) {
super(props)
this.state ={
users:this.props.userList
}
}
render() {
return (
<div className="container-fluid">
<br />
{
this.state.users.map((user)=>
<div className="jumbotron container">
{user.login}
</div>
)
}
</div>
);
}
}
export default UserList;

You have several problems in your components:
do not copy parent's state into chilren states: users:this.props.userList. Use this.props directly instead and React will know it must re-render children
do not rely on current state to set new state. Use function with prevState instead of isOpen: !this.state.isOpen.
make a copy of event's value before passing it to setState like this const {value} = e.target;
assign unique key to each user in your list (not indexes!), or it won't re-render correctly on list update
So your code would look like this:
class SearchHeader extends Component {
constructor(props) {
super(props);
this.state = {
errorMessage: '',
userList: [],
isOpen: false,
userName:''
};
}
toggle = () => {
this.setState( (prevState) => ({
isOpen: !prevState.isOpen
}));
}
getUsers = (e) => {
const {value} = e.target;
console.log('get users called='+value);
fetch('https://api.github.com/search/users?q='+ value)
...
}
}
and:
class UserList extends Component {
// Use default constructor
render() {
const users = this.props.userList.map( (user) => (
<div className="jumbotron container" key={user.login}>
{user.login}
</div>
));
return (
<div className="container-fluid">
<br />
{users}
</div>
);
}
}

parent component change should be.
getUsers(e) {
console.log('get users called='+e.target.value);
fetch('https://api.github.com/search/users?q='+ e.target.value)
.then(res => res.json())
.then(
userList =>{
this.setState({userList: userList.items})
console.log(userList);
}
);
}
Change your user list and check initially values are there or not and you dont need to user state in userList component.
that is all because initially there are no values also there can be an case when you are setting state for userList value after fetching data that might be coming as null undefined or something else so put an console log there and check that too.
class UserList extends Component {
render() {
return (
{
this.props.userList && this.props.userList.length && this.props.userList.map((user)=>
{user.login}
)
}
</div>
);
}
}
export default UserList;

Related

react redux two components

I have a component that will display the products which is coming from backend and a component that receives the products to filter but I have doubt that receive by redux my product list.
should i put for my filters component receive?
or should return the same as I get in my product component?
or should I create an action to filter what I need already?
my home:
return (
<div className="container">
<h1>Shopping</h1>
<hr />
<div className="row">
<div className="col-md-3"><Filters/></div>
<div className="col-md-9"><Products/></div>
</div>
</div>
)
my component products:
import React, { Component } from 'react'
import {connect} from 'react-redux'
import { ProductsFetchData } from '../../store/actions/productsFetch';
import util from '../../util';
class HomeProducts extends Component {
componentDidMount() {
this.props.fetchData('/products');
}
render() {
const productItems = this.props.products.map( product => (
<div className="col-md-4 pt-4 pl-2">
<div className = "thumbnail text-center">
<a href={`#${product.id}`} onClick={(e)=>this.props.handleAddToCard(e,product)}>
<p>
{product.name}
</p>
</a>
</div>
<b>{util.formatCurrency(product.price)}</b>
<button className="btn btn-primary" onClick={(e)=>this.props.handleAddToCard(e,product)}>Add to Cart</button>
</div>
)
)
return (
<div className="container">
<div className="row">
{productItems}
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
products: state.Products,
hasErrored: state.ProductsHasErrored,
isLoading: state.ProductsIsLoading
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchData: () => dispatch(ProductsFetchData())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeProducts);
my components filter
import React, { Component } from 'react';
import './style.css'
class FilterHome extends Component {
render() {
return (
<>
<div className="row">
<button className="filterbt btn btn-danger btn-rounded">Filters</button>
<div className=" mt-4 d-flex flex-column">
<p className="textCategory">CATEGORY</p>
<div className="category d-flex flex-column">
<p>Stat Trak</p>
<p>Normal</p>
</div>
<p className="textCategory">EXTERIOR</p>
<div className="category d-flex flex-column">
<p>Factory New ()</p>
<p>Minimal Wear ()</p>
<p>Field Tested ()</p>
<p>Well Worn ()</p>
<p>Battle Scarred ()</p>
</div>
</div>
</div>
</>
)
}
}
export default FilterHome;
1.redux-state: this is the registering point for all your api responses(all the data from back-end is stored here as prestine and is available as props to any container when you mapStateToProps).
2.local-state: this lives only in your container and all it's child components.
3.filter:
a)from server:
you make a request to the server and get a response of filtered products. this
is more practical.
eg: you have /products?page=1 and you want to search it by some category, let's
say by a specific company. with the data you have at the moment(page 1), you
may have only let's say 1 or even no product relevant to that company, but in fact there are n-numbers of products of the same company available at the server. so this can only be assumed as the
most practical way.
b)filtering from the local-state:
if this is what your'e trying to achieve,
1. you need only one container, HomeProducts
2. make ProductItems as a component. wer'e gonna reuse this component to render both.
**you wrote your filter as an independent container. but those filter functionality should be availabe inside the home page itself. isn't it, i mean you're filtering from the home page itself not from another page. if so, add it to the home page itself
1.HomePage
import React, { Component } from 'react'
import {connect} from 'react-redux'
import { ProductsFetchData } from '../../store/actions/productsFetch';
import util from '../../util';
import ProductItems from '<<..your relative path>>'
import FilterHome from '<<..your relative path>>'
class HomeProducts extends Component {
constructor(props) {
super(props)
this.state = {
productList: null,
}
}
componentDidMount() {
//this.props.fetchData('/products');
this.props.fetchData('page=1');
}
componentWillReceiveProps(nextProps) {
const { productList } = this.state
const { products } = this.props
// this only handles when local state is empty. add your logic here..
!productList && this.setState(prevState => ({
...prevState,
productList: products,
}))
}
handleFilter = (category) => {
// if it's an api call
const { fetchData } = this.props
fetchData(`page=1&category=${category}`)
//or you simply want to filter this local state(not-recommended)
const { products } = this.props
const productsList = [...products].filter(item => item.category === category)
this.setState(prevState => ({
...prevState,
productsList,
}))
}
render() {
const { productList } = this.state
const { handleFilter } = this
return (
<div className="container">
<FilterHome {...{ handleFilter }} />
<ProductItems {...{ productsList }} />
</div>
)
}
}
const mapStateToProps = (state) => {
return {
products: state.Products,
hasErrored: state.ProductsHasErrored,
isLoading: state.ProductsIsLoading
};
};
//it may not suit depends on your api, but you get the idea..
const mapDispatchToProps = (dispatch) => {
return {
// fetchData: () => dispatch(ProductsFetchData())
fetchData: params => dispatch(ProductsFetchData(`/products?${params}`))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(HomeProducts);
2.ProductItems
import React from 'react'
const ProductItem = ({ product }) => {
return (
<div className="col-md-4 pt-4 pl-2">
<div className = "thumbnail text-center">
<a href={`#${product.id}`} onClick={(e)=>this.props.handleAddToCard(e,product)}>
<p>
{product.name}
</p>
</a>
</div>
<b>{util.formatCurrency(product.price)}</b>
<button className="btn btn-primary" onClick={(e)=>this.props.handleAddToCard(e,product)}>Add to Cart</button>
</div>
)
}
const ProductItems = ({ productList }) => {
return (
<div className="row">
{productList && productList.map(product => <ProductItem key={product.id} {...{ product }} />)}
</div>
)
}
export default ProductItems
3.FilterHome
import React from 'react'
const FilterHome = ({ handleFilter }) => {
return (
<div className="row">
<button className="filterbt btn btn-danger btn-rounded">Filters</button>
<div className=" mt-4 d-flex flex-column">
<p className="textCategory">CATEGORY</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none" onClick={() => handleFilter('stat_trak')}><p>Stat Trak</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('normal')}><p>Normal</p></a>
</div>
<p className="textCategory">EXTERIOR</p>
<div className="category d-flex flex-column">
<a href="" className="text-decoration-none" onClick={() => handleFilter('factory_new')}><p>Factory New ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('minimal_wear')}><p>Minimal Wear ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('field_tested')}><p>Field Tested ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('well_worn')}><p>Well Worn ()</p></a>
<a href="" className="text-decoration-none" onClick={() => handleFilter('battle_scarred')}><p>Battle Scarred ()</p></a>
</div>
</div>
</div>
)
}
export default FilterHome
i roughly re-wrote it, may contain bugs..
first add it to the local state and employ a call back to the filter component..
handleFilter = (category) => {
const { Products } = this.state
const products = {...Products}
//or depends on the type, so it wont mutate the real data>> const products = [...Products]
return products.filter(item => item.category === category)
}
this is what is understood from your comment. is that it?

How to render reusable component one at a time in reactjs?

I reuse the Chat component twice into another component. It display when you click Chat button but it overlaps each other.
class Chat extends React.Component {
constructor() {
super();
this.state = {
show: false,
};
}
reset = () => {
this.setState(false);
}
open = () => {
this.setState({ show: true });
}
close = () => this.setState({ show: false });
render() {
return (<div className="chat">
<button className="btn-yes round" onClick={this.open}>{this.props.title}</button>
{this.state.show &&
<div className="show-chat">
<div className="chat-head">Now Chatting <i className="fas fa-angle-down" onClick={this.close}></i></div>
<div className="chat-body">
<div className="blue">Teresa wants to chat about her healthcare finances</div>
<ul>
<li><img src={agentPhoto} alt="chat agent avatar" /></li>
<li>
<h6>John Newman</h6>
<div className="gray">Hi Teresa!</div>
<div className="gray">Here is the link to the finance tool we discussed.</div>
<div className="gray">If you have any questions, let me know!</div>
</li>
</ul>
</div>
<input placeholder="Type here and hit enter to chat"></input>
</div>}
</div>);
}
}
I expect to display chat one at a time. When I click the Chat button 2 and the Chat 1 is displayed, Chat 1 should be hidden.
Essentially, you need to give each Chat component an identifier and keep track of the one that is currently opened.
Here is the basic structure for your Parent component:
class App extends React.Component {
state = {
currentChatId: null
};
handleOpen = id => {
this.setState({
currentChatId: id
});
};
render() {
return (
<div>
<Chat
identifier={1}
currentChatId={this.state.currentChatId}
handleOpen={this.handleOpen}
/>
<Chat
identifier={2}
currentChatId={this.state.currentChatId}
handleOpen={this.handleOpen}
/>
</div>
);
}
}
So notice, we give each Chat component an identifier prop. We will use identifier to update the active chat - which we stored as a value called currentChatId in our parent-state. That is all done through the handleOpen() event-handler, which we also pass down as a prop to Chat.
Now in your Chat component, we need to configure logic for open() and componentDidUpdate()
class Chat extends React.Component {
constructor() {
super();
this.state = {
show: false
};
}
componentDidUpdate(prevProps) {
const { identifier, currentChatId } = this.props;
if (this.props.currentChatId !== prevProps.currentChatId) {
this.setState({
show: identifier === currentChatId ? true : false
});
}
}
open = () => {
const { identifier, handleOpen } = this.props;
handleOpen(identifier);
};
render() {
return (
<div className="chat">
<button className="btn-yes round" onClick={this.open}>
{this.props.title}
</button>
{this.state.show && (
<div className="show-chat">
<div className="chat-head">
Now Chatting{" "}
<i className="fas fa-angle-down" onClick={this.close} />
</div>
<div className="chat-body">
<div className="blue">
Teresa wants to chat about her healthcare finances
</div>
<ul>
<li>
<img src={""} alt="chat agent avatar" />
</li>
<li>
<h6>John Newman</h6>
<div className="gray">Hi Teresa!</div>
<div className="gray">
Here is the link to the finance tool we
discussed.
</div>
<div className="gray">
If you have any questions, let me know!
</div>
</li>
</ul>
</div>
<input placeholder="Type here and hit enter to chat" />
</div>
)}
</div>
);
}
}
Workflow:
User clicks one of the Chat buttons, triggering handleOpen()and we
pass in the unique identifier....
That gets passed back up to the Parent, and now currentChatId
should be updated with the identifier...
That currentChatId gets passed back down to the Chat component as the
currentChatId prop...
Triggers componentDidUpdate() on all Chat components, and we check
the currentChatId against their own identifiers, only one will be
matching, so we display that one.
See codesandbox for working example: https://codesandbox.io/s/react-example-kgm2h

TypeError: this.props.likeMovie is not a function

i am using ReactJs and firebase.
I have this error when i try to push "like data" to the db.
All i want is to set the movie like to 1 instead of 0.
I have a Movie DB api which i use to fetch and display movie info to the user.
then i use firebase authentication to log in and then the user clicks the like button and it should save the value 1 to the db.
I am new to React and don't fully understand the concepts, so if its something stupid i'm sorry.
Here is the error:
TypeError: this.props.likeMovie is not a function
AddLike.likeMovie
C:////
23 | this.setState({
24 | newMovieContent: 1,
25 | })
> 26 | this.props.likeMovie(this.state.newMovieContent);
27 | }
28 |
29 | render(){
Here is the code:
import React, { Component } from 'react';
class AddLike extends Component{
constructor(props){
super(props);
this.state = {
newMovieContent: 0,
};
this.handleUserInput = this.handleUserInput.bind(this);
this.likeMovie = this.likeMovie.bind(this);
}
likeMovie(){
this.setState({
newMovieContent: 1,
})
this.props.likeMovie(this.state.newMovieContent);
}
render(){
return(
<div>
<button
onClick={this.likeMovie}>Like</button>
</div>
)
}
}
export default AddLike;
Movie row
addMovieRecord is adding like value 1, will have more data later.(that is why called that instead of addlike)
class MovieRow extends React.Component {
constructor(props, context) {
super(props, context);
this.addMovieRecord = this.addMovieRecord.bind(this);
this.removeMovie = this.removeMovie.bind(this);
this.app = fire;
this.database = this.app.database().ref().child('movies');
this.state = {
show: false,
movies: [],
};
componentWillMount(){
const previousMovies = this.state.movies;
//ADD
this.database.on('child_added', snap => {
previousMovies.push({
id: snap.key,
movieRecord: snap.val().movieRecord,
})
this.setState({
movies: previousMovies
})
})
//REMOVE
this.database.on('child_removed', snap => {
for(var i=0; i < previousMovies.length; i++){
if(previousMovies[i].id === snap.key){
previousMovies.splice(i, 1);
}
}
this.setState({
movies: previousMovies
})
})
}
//ADD
addMovieRecord(movie){
this.database.push().set({movieRecord: movie});
}
//REMOVE
removeMovie(movieId){
this.database.child(movieId).remove();
}
render() {
return <div key={this.props.movie.id}>
<div className="row">
<div className="col-md-4 card card-body">
<img src={this.props.movie.poster_src} style={{width:'15em', height:'20em'}}
className="thumbnail" alt="Poster" />
</div>
<div className="col-md-8">
<h2 className="mb-4">{this.props.movie.title}</h2>
<ul className="list-group">
<li className="list-group-item">
<strong>Released:</strong> {this.props.movie.release_date}
</li>
<li className="list-group-item">
<strong>Rated:</strong> {this.props.movie.popularity}
</li>
<li className="list-group-item">
<AddLike addMovieRecord={this.addMovieRecord}/>
{
this.state.movies.map((movie) => {
return (
<Movie movieRecord={movie.movieRecord}
moviId={this.props.movie.id}
key={this.props.movie.id}
removeNote ={this.removeNote}/>
)
})
}
</li>
</ul>
</div>
</div>
<>
<Button variant="primary" onClick={this.handleShow}>
Show More Information
</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>{this.props.movie.title}</Modal.Title>
</Modal.Header>
<Modal.Body>{this.props.movie.overview}</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={this.handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
<hr/>
</div>
}
}
export default MovieRow
Thanks in advance.
The function passed in as a prop to the AddLike component is called addMovieRecord, so you need to call this.props.addMovieRecord instead of this.props.likeMovie.
setState is also asynchronous, so using this.state.newMovieContent directly after updating it will not give you the latest value. You can call addMovieRecord in a callback given to setState instead:
likeMovie(){
this.setState({
newMovieContent: 1,
}, () => {
this.props.addMovieRecord(this.state.newMovieContent);
});
}

Does not showing indiviual state in react js?

showing the same state,but i want display indiviual state.when i click the hospital its not showing hospital component but both hospital,fireservice showing same state.click function worked but not showing the indiviual component only showing same component
import React, { Component } from 'react';
import './importantplaces.css';
import Showhospital from './Hospitallist/Showhospital';
import Showfireservice from './Fireservice/Showfireservice';
export default class Importantplaces extends Component {
constructor() {
super();
this.state = {
showHospital: false,
showFire: false
}
}
onClick(e) {
e.preventDefault();
this.setState({ showHospital: !this.state.showHospital })
this.setState({ showFire: !this.state.showFire })
}
render() {
return (
<div className="Importantplaces">
<div className="placelist">
<div className="container-fluid">
<div className="row">
<div className="col-md-6">
<a onClick={this.onClick.bind(this)} className="place-content p-btn mb-70">Hospital</a>
<a onClick={this.onClick.bind(this)} className="place-content p-btn mb-70">Fire Service</a>
</div>
<div className="col-md-6">
<a onClick={this.onClick.bind(this)} className="place-content p-btn mb-70">Police Station</a>
<a onClick={this.onClick.bind(this)} className="place-content p-btn mb-70">Post Office</a>
</div>
</div>
</div>
</div>
{this.state.showHospital && <Showhospital />}
{this.state.showFire && <Showfireservice />}
</div>
);
}
}
Please check below code you can use one function to onclick
class B extends React.Component {
render(){
return(
<div>
<h1>BBBB</h1>
</div>
);
}
}
class C extends React.Component {
render(){
return(
<div>
<h1>CCCC</h1>
</div>
);
}
}
class A extends React.Component {
constructor() {
super();
this.state = {
showB: false,
showC: false,
}
this.handleMultiSelect = this.handleMultiSelect.bind(this);
}
handleMultiSelect(val) {
console.log('aaaa', val);
if(val === 'b'){
this.setState({
showB: !this.state.showB
});
} else if(val === 'c'){
this.setState({
showC: !this.state.showC
});
}
}
render() {
return (
<div>
<a onClick={() => {this.handleMultiSelect('b')}}>B</a>
<br />
<a onClick={() => {this.handleMultiSelect('c')}}>C</a>
{this.state.showB && <B/>}
{this.state.showC && <C/>}
</div>
);
}
}
ReactDOM.render( < A / > , 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>
Right now you are changing both your state on the click event. So they both always go from false to true and back to false.
You have different way to solve this : adding an argument to your onclick function to define which state should go to true, or making different onClick function for each component you want to show. Second solution would go as such :
<a onClick={this.onHospitalClick.bind(this)} className="place-content p-btn mb-70">Hospital</a>
<a onClick={this.onFireServiceClick.bind(this)} className="place-content p-btn mb-70">Fire Service</a>
and having these two functions instead :
onHospitalClick(e) {
e.preventDefault();
this.setState({ showHospital: true, showFire : false })
}
onFireServiceClick(e) {
e.preventDefault();
this.setState({ showHospital: false, showFire : true })
}

React: change order list when button clicked

I am making my first app with Javascript and React and started with a page which views a shopping list. It gets the items from an api call.
If the user clicks on the button 'done' (or should I use an checkbox?) This product should go to the bottom of the list (and be grayed out with css but thats not the problem).
The problem is, I have no clue how to do this. Can anyone help me out a bit?
This is my code:
import React from 'react';
//import image from '../images/header.png';
//import Collapsible from './Collapsible';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
orders: []
}
}
componentWillMount() {
localStorage.getItem('orders') && this.setState({
orders: JSON.parse(localStorage.getItem('orders')),
isLoading: false
})
}
componentDidMount() {
if (!localStorage.getItem('orders')){
this.fetchData();
} else {
console.log('Using data from localstorage');
}
}
fetchData() {
fetch('http://localhost:54408/api/orders/all/15-03-2018')
.then(response => response.json())
.then(parsedJSON => parsedJSON.map(product => (
{
productname: `${product.ProductName}`,
image: `${product.Image}`,
quantity: `${product.Quantity}`,
isconfirmed: `${product.IsConfirmed}`,
orderid: `${product.OrderId}`
}
)))
.then(orders => this.setState({
orders,
isLoading: false
}))
.catch(error => console.log('parsing failed', error))
}
componentWillUpdate(nextProps, nextState) {
localStorage.setItem('orders', JSON.stringify(nextState.orders));
localStorage.setItem('ordersDate', Date.now());
}
render() {
const {isLoading, orders} = this.state;
return (
<div>
<header>
<img src="/images/header.jpg"/>
<h1>Boodschappenlijstje <button className="btn btn-sm btn-danger">Reload</button></h1>
</header>
<div className={`content ${isLoading ? 'is-loading' : ''}`}>
<div className="panel">
{
!isLoading && orders.length > 0 ? orders.map(order => {
const {productname, image, quantity, orderid} = order;
return<div className="product" key={orderid}>
<div className="plaatjediv">
<img className="plaatje" src={image} />
</div>
<div className="productInfo">
<p>{productname}</p>
<p>Aantal: {quantity}</p>
<p>ID: {orderid}</p>
</div>
<div className="bdone">
<button className="btn btn-sm btn-default btndone">Done</button>
</div>
</div>
}) : null
}
</div>
<div className="loader">
<div className="icon"></div>
</div>
</div>
</div>
);
}
}
export default App;
You can achieve by using this :
this.handleDoneAction = event = > {
let itemIndex = event.target.getAttribute("data-itemIndex");
let prevOrders = [...this.state.orders];
var itemToMoveAtLast = prevOrders.splice(itemIndex, 1);
var updatedOrderList = prevOrders.concat(itemToMoveAtLast);
this.setState({order: updatedOrderList})
}
I have attach an event handler on the button handleDoneAction.
<button className="btn btn-sm btn-default btndone" data-itemIndex={index} onClick={this.handleDoneAction}>Done</button>
the attribute data-itemIndex is the index of the object in orders array.
And your map function will be like this:
orders.map((order, index) => {
//content
})
ANd for the different style effects on the done products, I will suggest you to use different array for all done products.

Resources