Home > Enterprise >  Conditional visibility in a react component
Conditional visibility in a react component

Time:05-04

I have a react component that contains a div with a conditional visibility. The component represents the page of a specific product on an ecommerce. The users can give their opinions once. The div with the conditional visibility contains a textarea to write this opinion. But it should only be visible if the user hasn't written a review yet. This decision must be taken before loading the component. How do I do that?

This is the component:

import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";

function Product() {
  //Visivility of the form

  
  let visibility = false;
  useEffect(() => {
    Axios.get("http://localhost:3001/review").then((response) => {
      if (response.data.length === 0) {
        visibility = true;
      }
    });
  }, []);

  const idprod = useParams();
  
  //POST of the review
  function handleSubmit(event) {
    event.preventDefault();
    let info = {
      message: event.target.review.value,
      rating: event.target.stars.value
    };
    if (!info.message || !info.rating) {
      if (!info.message) {
        alert("You haven't witten a review");
      } else if (!info.rating) {
        alert("You haven't give any stars");
      }
    } else {
      Axios.post("http://localhost:3001/review", {
        message: info.message,
        rating: info.rating,
        id_prod: idprod
      }).then((response) => {
        if (response.data.err) {
          alert("You have already written a review for this product");
        }
      });
    }
  }
  return (
    <div>
      <NavbarHome />
      <div className="container-fluid" id="container-producto">
        <div className="row">

          <div className="col-sm-6 bloque-description-product">
            <h2>Example</h2>
            <p>Example</p>
            <p>Example</p>
            <p>Example</p>
          </div>
        
        </div>

        <h4>Opinions</h4>
        <div className="container-opinions">
          {visibility ? (
            <form onSubmit={handleSubmit}>
              <p className="clasification">
                <input id="radio1" type="radio" name="stars" value="5" />
                <label htmlFor="radio1">★</label>
                <input id="radio2" type="radio" name="stars" value="4" />
                <label htmlFor="radio2">★</label>
                <input id="radio3" type="radio" name="stars" value="3" />
                <label htmlFor="radio3">★</label>
                <input id="radio4" type="radio" name="stars" value="2" />
                <label htmlFor="radio4">★</label>
                <input id="radio5" type="radio" name="stars" value="1" />
                <label htmlFor="radio5">★</label>
              </p>
              <textarea
                name="review"
                placeholder="Leave your review..."
              ></textarea>
              <input type="submit"></input>
            </form>
          ) : (
            <div></div>
          )}
        </div>
      </div>
    </div>
  );
}

export default Product;

The div with the conditional visibility is container-opinions.

I've already tried using onLoad on that container, but it is not working.

Any ideas?

CodePudding user response:

You should change let variable with react state

import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";

    function Product() {
      const [visibility, setVisibility] = useState(false)
      
      useEffect(() => {
        Axios.get("http://localhost:3001/review").then((response) => {
          if (response.data.length === 0) {
            setVisibility(true);
          }
        });
      }, []);
    
      const idprod = useParams();
      
      //POST of the review
      function handleSubmit(event) {
        event.preventDefault();
        let info = {
          message: event.target.review.value,
          rating: event.target.stars.value
        };
        if (!info.message || !info.rating) {
          if (!info.message) {
            alert("You haven't witten a review");
          } else if (!info.rating) {
            alert("You haven't give any stars");
          }
        } else {
          Axios.post("http://localhost:3001/review", {
            message: info.message,
            rating: info.rating,
            id_prod: idprod
          }).then((response) => {
            if (response.data.err) {
              alert("You have already written a review for this product");
            }
          });
        }
      }
      return (
        <div>
          <NavbarHome />
          <div className="container-fluid" id="container-producto">
            <div className="row">
    
              <div className="col-sm-6 bloque-description-product">
                <h2>Example</h2>
                <p>Example</p>
                <p>Example</p>
                <p>Example</p>
              </div>
            
            </div>
    
            <h4>Opinions</h4>
            <div className="container-opinions">
              {visibility ? (
                <form onSubmit={handleSubmit}>
                  <p className="clasification">
                    <input id="radio1" type="radio" name="stars" value="5" />
                    <label htmlFor="radio1">★</label>
                    <input id="radio2" type="radio" name="stars" value="4" />
                    <label htmlFor="radio2">★</label>
                    <input id="radio3" type="radio" name="stars" value="3" />
                    <label htmlFor="radio3">★</label>
                    <input id="radio4" type="radio" name="stars" value="2" />
                    <label htmlFor="radio4">★</label>
                    <input id="radio5" type="radio" name="stars" value="1" />
                    <label htmlFor="radio5">★</label>
                  </p>
                  <textarea
                    name="review"
                    placeholder="Leave your review..."
                  ></textarea>
                  <input type="submit"></input>
                </form>
              ) : (
                <div></div>
              )}
            </div>
          </div>
        </div>
      );
    }
    
    export default Product;

CodePudding user response:

You'll want to use the useState react hook to keep track of the visibility in a way your app can react to:

import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";

function Product() {
  //Visivility of the form
  // THIS NEEDS TO BE useState
  const [visibility, setVisibility] = useState(false)
  
  useEffect(() => {
    Axios.get("http://localhost:3001/review").then((response) => {
      if (response.data.length === 0) {
        // Use setVisibility to update the state
        setVisibility(true);
      }
    });
  }, []);

  const idprod = useParams();
  
  //POST of the review
  function handleSubmit(event) {
    event.preventDefault();
    let info = {
      message: event.target.review.value,
      rating: event.target.stars.value
    };
    if (!info.message || !info.rating) {
      if (!info.message) {
        alert("You haven't witten a review");
      } else if (!info.rating) {
        alert("You haven't give any stars");
      }
    } else {
      Axios.post("http://localhost:3001/review", {
        message: info.message,
        rating: info.rating,
        id_prod: idprod
      }).then((response) => {
        if (response.data.err) {
          alert("You have already written a review for this product");
        }
      });
    }
  }
  return (
    <div>
      <NavbarHome />
      <div className="container-fluid" id="container-producto">
        <div className="row">

          <div className="col-sm-6 bloque-description-product">
            <h2>Example</h2>
            <p>Example</p>
            <p>Example</p>
            <p>Example</p>
          </div>
        
        </div>

        <h4>Opinions</h4>
        <div className="container-opinions">
          {visibility ? (
            <form onSubmit={handleSubmit}>
              <p className="clasification">
                <input id="radio1" type="radio" name="stars" value="5" />
                <label htmlFor="radio1">★</label>
                <input id="radio2" type="radio" name="stars" value="4" />
                <label htmlFor="radio2">★</label>
                <input id="radio3" type="radio" name="stars" value="3" />
                <label htmlFor="radio3">★</label>
                <input id="radio4" type="radio" name="stars" value="2" />
                <label htmlFor="radio4">★</label>
                <input id="radio5" type="radio" name="stars" value="1" />
                <label htmlFor="radio5">★</label>
              </p>
              <textarea
                name="review"
                placeholder="Leave your review..."
              ></textarea>
              <input type="submit"></input>
            </form>
          ) : (
            <div></div>
          )}
        </div>
      </div>
    </div>
  );
}

export default Product;
  • Related