0

1st, please ignore my bad English. I'm a reactJS fresher, and I've got a issue as I wrote on title. I saw that adding more product into ProductList by array.push() successfully, but table was not updated... Beside, I tried the way like use setState, but it did not work. I'm still stuck and hope somebody show me the way to solve it, deeply appreciate it!

This is columns in index.js file:

const Columns = [
{
  name: '#',
  selector: 'productCode',
  center: true,
  width: '5rem',
},
{
  name: <FormattedMessage {...messages.productName}/>,
  selector: 'productName',
  center: true,
},
{
  name: <FormattedMessage {...messages.productDescription}/>,
  selector: 'productDescription',
  center: true,
},
{
  name: <FormattedMessage {...messages.productPrice}/>,
  selector: 'productPrice',
  center: true,
},
{
  name: <FormattedMessage {...messages.productQuantity}/>,
  selector: 'productQuantity',
  center: true,
},
{
  name: <FormattedMessage {...messages.totalPrice}/>,
  selector: 'totalPrice',
  center: true,
},
{
  name: <FormattedMessage {...messages.action}/>,
  selector: 'action',
  center: true,
},];

This is data for table :

  const [ProductList, setProductList] = useState([
{
  productCode:1,
  productName: <Input type="text" defaultValue="Product 1" className="text-center" />,
  productDescription:<Input type="text" defaultValue="description 1" className="text-center" />,
  productPrice: <Input type="number" defaultValue="1000" className="text-center" />,
  productQuantity: <Input type="number" defaultValue="10" className="text-center" />,
  totalPrice:10000,
  action: <Button color="danger" onClick={deleteProduct}>
            <FontAwesomeIcon className="mr-2" icon="times"/>
            <FormattedMessage {...messages.deleteProduct}/>
          </Button>,
},
{
  productCode:2,
  productName: <Input type="text" defaultValue="Product 2" className="text-center" />,
  productDescription:<Input type="text" defaultValue="description 2" className="text-center" />,
  productPrice: <Input type="number" defaultValue="1000" className="text-center" />,
  productQuantity: <Input type="number" defaultValue="10" className="text-center" />,
  totalPrice:10000,
  action: <ButtonAsync color="danger">
            <FontAwesomeIcon className="mr-2" icon="times"/>
            <FormattedMessage {...messages.deleteProduct}/>
          </ButtonAsync>,
},
{
  productCode:3,
  productName: <Input type="text" defaultValue="Product 3" className="text-center" />,
  productDescription:<Input type="text" defaultValue="description 3" className="text-center" />,
  productPrice: <Input type="number" defaultValue="1000" className="text-center" />,
  productQuantity: <Input type="number" defaultValue="10" className="text-center" />,
  totalPrice:10000,
  action: <ButtonAsync color="danger">
            <FontAwesomeIcon className="mr-2" icon="times"/>
            <FormattedMessage {...messages.deleteProduct}/>
          </ButtonAsync>,
},
]);

This is add function :

const addProduct = () => {
let product = {
  productCode: ProductList[ProductList.length - 1].productCode + 1,
  productName: <Input type="text" defaultValue="" className="text-center" />,
  productDescription:<Input type="text" defaultValue="" className="text-center" />,
  productPrice: <Input type="number" defaultValue="" className="text-center" />,
  productQuantity: <Input type="number" defaultValue="" className="text-center" />,
  totalPrice:'',
  action: <ButtonAsync color="danger">
            <FontAwesomeIcon className="mr-2" icon="times"/>
            <FormattedMessage {...messages.deleteProduct}/>
          </ButtonAsync>,
};
ProductList.push(product);
console.log(ProductList);

}

And this is Data Table :

<Col xs={12}>
                <div className="general-info">
                  <div className="d-flex justify-content-between">
                    <div className="text-uppercase title-block mt-3 mb-3">
                      <FormattedMessage {...messages.productSelected} />
                    </div>
                    <div className="mt-2 mb-3">
                    <Button color="success" style={{width:'130px'}} onClick={addProduct}>
                      <FontAwesomeIcon className="mr-2" icon="plus"/>
                      <FormattedMessage {...messages.addProduct}/>
                    </Button>

                  </div>
                  </div>
                    <TableData
                      title=""
                      columns={Columns}
                      data={ProductList}
                      className="table"
                      noHeader={true}
                      pagination={true}
                      paginationServer={true}
                    />
                  </div>
              </Col>

This is Data Table index.js :

import React, { memo } from 'react';
import styled from 'styled-components';
import { Table } from 'reactstrap';
import DataTable from 'react-data-table-component';
import StyledTableData from './StyledTableData';

const StyledThead = styled.thead`
color: #807777;
  th {
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
    text-align: center;
    border-bottom-width: 1px;
  }
`;
const StyledMessage = styled.div`
  padding: 1rem;
  width: 100%;
  display: flex;
  justify-content: center;
  background-color: rgb(240,249,252);
  >p {
    margin-bottom: 0;
    padding: 1rem 0;
  }
`;
function TableData(props) {
const noDataComponent = (
    <>
        <Table>
            <StyledThead>
                <tr>
                    {props && props.columns && props.columns.map((item, index) => (
                        <th key={index}>{item.name}</th>
                    ))}
                </tr>
            </StyledThead>
        </Table>
        <StyledMessage>
            <p>Không có dữ liệu bảng</p>
        </StyledMessage>
    </>
);
return <StyledTableData><DataTable {...props}  noDataComponent={noDataComponent}/></StyledTableData>;

}

1 Answer 1

1

Actually you can't update the react component state with push method in array, you should use react setState or as I see in your example that you are using hooks, you should use setProductList to update the ProductList.

So, you should use something like this:

const addProduct = () => {
  let newProduct = {
    productCode: ProductList[ProductList.length - 1].productCode + 1,
    productName: <Input type="text" defaultValue="" className="text-center" />,
    productDescription: <Input type="text" defaultValue="" className="text-center" />,
    productPrice: <Input type="number" defaultValue="" className="text-center" />,
    productQuantity: <Input type="number" defaultValue="" className="text-center" />,
    totalPrice: '',
    action: (
      <ButtonAsync color="danger">
        <FontAwesomeIcon className="mr-2" icon="times" />
        <FormattedMessage {...messages.deleteProduct} />
      </ButtonAsync>
    ),
  };

  setProductList([...ProductList, newProduct]);

  console.log(ProductList);
};
Sign up to request clarification or add additional context in comments.

2 Comments

Tks alot, I will try now. Actually, I'd tried this way before but there're some diffs, it did not work at all. Hope it will work this time...
prob solved, tks @Arman... use setProductList directly, like let newProductList = [...productList]; newProductList.push(newProduct); setProductList(newProductList); and voila!, it work for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.