Home > OS >  Is there a way to put const values in a useState({})
Is there a way to put const values in a useState({})

Time:03-24

I'm pretty new to react, and I'm working on a component where I'm calculating the percentages of values in below useState, so for instance:

    const [data, setData] = useState({ five: 5, four: 4, three: 3, two: 2, one: 1 });
    const [percentage, setPercentage] = useState(0);

   const fields = [
      { name: "five", value: data.five },
      { name: "four", value: data.four },
      { name: "three", value: data.three },
      { name: "two", value: data.two },
      { name: "one", value: data.one }
    ];

 useEffect(() => {
      const per1 = ((data.one) / (data.five   data.four   data.three   data.two   data.one)) * 100;
      setPercentage(per1);

    }, [data]);
  

I have constants that I created to calculated the amount of ratings for each type of rating for instance: the number of five star, four star, etc. :

    const numRating5 = product.reviews.filter((x) => x.rating === 5);
    const numRating4 = product.reviews.filter((x) => x.rating === 4);
    const numRating3 = product.reviews.filter((x) => x.rating === 3);
    const numRating2 = product.reviews.filter((x) => x.rating === 2);
    const numRating1 = product.reviews.filter((x) => x.rating === 1);

Is there a way for me to put the numRating5, numRating4,.... in their respective positions (five:5, four:4,...) in the useState. I would really appreciate any help or guidance on this. Thank you!

CodePudding user response:

You can try something like this:

const product = {
  reviews: [
    {rating: 1},
    {rating: 2},
    {rating: 3},
    {rating: 4},
    {rating: 5},
  ]
};

const getNumRating = (num) => product.reviews.filter((x) => x.rating === num).length;

const numRating5 = getNumRating(5);
const numRating4 = getNumRating(4);
const numRating3 = getNumRating(3);
const numRating2 = getNumRating(2);
const numRating1 = getNumRating(1);

const useState = React.useState;
const useEffect = React.useEffect;

function App() {
  const [data, setData] = useState({
    five: numRating5,
    four: numRating4,
    three: numRating3,
    two: numRating2,
    one: numRating1
  });
  const [percentage, setPercentage] = useState(0);
  
  useEffect(() => {
      const per1 = (
        data.one / (data.five   data.four   data.three   data.two   data.one)
      ) * 100;
      setPercentage(per1);

    }, [data]);
  
  return (
    <div>
      Hello! Percentage = {percentage}
    </div>
  );
}

ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

CodePudding user response:

you can update the data using setData and pass the object

 setData ({
     five : numRating5,
     four : numRating4,
     three : numRating3,
     two : numRating2,
     one : numRating1,
});

please check: https://reactjs.org/docs/hooks-state.html for further information

CodePudding user response:

You can pass any data to useState but the shape of it should generally match what you intend to use in the state variable you declare with it. The state variable should represent a useful way to work with your data.

Since we generally use state to keep track of changing data in our apps, below is just an another example that may help to think about this as well as some useful patterns for updating state along with getting your percentage and using it on render. You're working with a list of reviews for each star rating level as I see it. This example can apply to bigger lists or lists of entirely different objects too.

The idea is each object consistently describes the features or information you need about each thing (in your case a list of reviews) allowing for methods of working with the data that avoid the need for individually calculating values (avoiding the repetition of something like per1 or numRatingX as the size or shape of your data changes).

https://codesandbox.io/s/tender-brattain-gu3d7f?file=/src/App.js:0-1064

Click the button to reset the review data with random values and see percentages update.

import { useState } from "react";

const App = () => {
  const seedRatings = [
    { stars: "5", reviews: 134 },
    { stars: "4", reviews: 177 },
    { stars: "3", reviews: 67 },
    { stars: "2", reviews: 55 },
    { stars: "1", reviews: 21 }
  ];

  const [ratings, setRatings] = useState(seedRatings);

  const total = ratings.reduce((total, rating) => total   rating.reviews, 0);

  // some thing that changes your data
  const handleChangeReviews = () => {
    // say we get some new ratings
    const newRatings = ratings.map((rating) => {
      return { ...rating, reviews: Math.floor(Math.random() * 100) };
    });

    setRatings(newRatings);
  };

  return (
    <div>
      {ratings &&
        ratings.map(({ stars, reviews }) => (
          <div key={stars}>
            <span>{stars} star reviews: </span>
            <span>{reviews} </span>
            <span>Percent of total: {(reviews / total) * 100}%</span>
          </div>
        ))}
      <button onClick={handleChangeReviews}>Change reviews</button>
    </div>
  );
};

export default App;
  • Related