M R
M R

Reputation: 17

How to call the state again when added or deleted new information in ReactJS without manually refresh the page?

I've been facing a problem. I already tried to solve it. But, I don't know how to get it to work. I know my problem is that I don't reupdate the Lists New state after I push or delete to the API? How can I fix this? So, I don't have to manually refresh the page?

I have 2 components but in this post, I will only show the one I use for delete and read from API this post, which is called "Products". The PostForm component is a separate component that is imported into the Create/Delete component.

I added this code in the setState for delete. I guess I need a function to reupdate the state but don't know-how. would appreciate help // productList: filter((item) => item.id !== productId),

class Products extends Component {
  state = {
    productList: [],
    statusMsg: "",
  };

  // READ
  getDataFromProductsApi() {
    axios
      .get("https://localhost:44366/api/Products/")
      .then((res) => {
        console.log(res.data);
        this.setState({
          productList: res.data,
        });
      })
      .catch((error) => {
        console.log(error);
        this.setState({ statusMsg: "Error retreiving data" });
        if (axios.isCancel(error)) return;
      });
  }
  componentDidMount() {
    this.getDataFromProductsApi();
  }

  // DELETE

  deleteProduct = (productId, productName) => {
    if (window.confirm("Are you sure? you want to delete")) {
      axios
        .delete(`https://localhost:44366/api/Products/${productId}`)
        .then((response) => {
          console.log(response);
          this.setState({
            statusMsg: `Product name: ${productName} With the ID: ${productId} was removed!`,
            // productList: filter((item) => item.id !== productId),
          });
        });
    }
  };

  showProducts = () => {
    return (
      <table className="customers">
        <tbody>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Category</th>
            <th>Price</th>
            <th>Delete</th>
          </tr>

          {this.state.productList.map((product) => {
            return (
              <tr key={product.id}>
                <td>{product.id}</td>
                <td>{product.name}</td>
                <td>{product.category}</td>
                <td>{product.price}</td>
                <td>
                  <button
                    onClick={() => this.deleteProduct(product.id, product.name)}
                  >
                    X
                  </button>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    );
  };

  render() {
    return (
      <header className="App-header">
        <div>
          <h1>Products</h1>
          <Postform /> {/*Adding the post Component to the view */}
          <div> {this.state.statusMsg}</div>
          {this.showProducts()} {/*running function to show data view */}
        </div>
      </header>
    );
  }
}

Upvotes: 0

Views: 86

Answers (1)

ZombieTfk
ZombieTfk

Reputation: 722

Is something like this what you mean?

https://jsfiddle.net/bq8h7ns9/

class Products extends React.Component {
  state = {
    productList : [],
    statusMsg: "",
  };

  // READ
  getDataFromProductsApi() {
    this.setState({
      productList: [{ id : 0, name: 'blah1', price: 12.3, category : 'blah' }, { id : 1, name: 'blah2', price: 32.1, category : 'blah' }],
    });
  }
  
  componentDidMount() {
    this.getDataFromProductsApi();
  }

  // DELETE

  deleteProduct = (productId, productName) => {
    if (window.confirm("Are you sure? you want to delete")) {
      this.setState({
        statusMsg: `Product name: ${productName} With the ID: ${productId} was removed!`,
        productList: this.state.productList.filter((item) => item.id !== productId),
      });
    }
  };

  showProducts = () => {
    return (
      <table className="customers">
        <tbody>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Category</th>
            <th>Price</th>
            <th>Delete</th>
          </tr>

          {this.state.productList.map((product) => {
            return (
              <tr key={product.id}>
                <td>{product.id}</td>
                <td>{product.name}</td>
                <td>{product.category}</td>
                <td>{product.price}</td>
                <td>
                  <button
                    onClick={() => this.deleteProduct(product.id, product.name)}
                  >
                    X
                  </button>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    );
  };

  render() {
    return (
      <header className="App-header">
        <div>
          <h1>Products</h1>
          <div> {this.state.statusMsg}</div>
          {this.showProducts()} {/*running function to show data view */}
        </div>
      </header>
    );
  }
}

You are already updating the component's state; that is what setState does. Your commented out line should be something like this.state.productList.filter((item) => item.id !== productId), filter is not a global function.

If you mean you want your component to stay in sync with your api, then you will need to use something like websockets or long polling. Http is a stateless protocol.

Upvotes: 1

Related Questions