N
N
NyGdeVragi2021-07-04 15:27:21
JavaScript
NyGdeVragi, 2021-07-04 15:27:21

The functionality is executed only when the state of the price of the first component changes. how to remove it?

There is a table, I divided it into two components: the table itself, in which I make a request to the server and draw the row component through map. I added functionality: when the price value changes, the background of this cell changes to red / green and after a second the background is removed. The problem is that the background changes in all lines and only when the price of the first crypt changes.

function Crypts() {

  const [cryptList, setCryptList] = useState([]);
  const [isAllShown, setIsAllShown] = useState(false)

  useEffect(() => {
    const fetchData = async () => {
      try {
        const { data: { data } } = await axios.get('https://api.coincap.io/v2/assets');
        setCryptList(data);

        //let timer = setTimeout(() => {
        //	fetchData();
        //   clearTimeout(timer)
        //}, 5000);
      } catch (e) {
        console.log(e)
      }
    }
    fetchData();
  }, [])



  return (
    <div className={classes.Crypts}>
      <table>
        <thead>
          <tr>
            <th>Название</th>
            <th>Тикер</th>
            <th>Цена(USD)</th>
            <th>Рын.кап.</th>
            <th>Объем(24ч)</th>
            <th>Изм. (24ч)</th>
          </tr>
        </thead>
        <tbody>
          {
            cryptList ?
              isAllShown ?
                cryptList.map((crypt, i) => {
                  return (
                    <CryptItem
                      key={i}
                      crypt={crypt}
                    />
                  )
                })
                :
                cryptList.filter(item => item.rank <= 10)
                  .map((crypt, i) => {
                    return (
                      <CryptItem
                        key={i}
                        crypt={crypt}
                      />
                    )
                  })
              :
              null
          }
        </tbody>
      </table>
      <button
        onClick={() => setIsAllShown(!isAllShown)}
      >
        {isAllShown ? "Скрыть все <<<" : "Показать все >>>"}
      </button>
    </div>
  )

}

export default Crypts;


export const CryptItem = ({ crypt }) => {


  const [cls, setCls] = useState([]);

  function usePrevious(value) {
    const ref = useRef();
    useEffect(() => {
      ref.current = value;
    });
    return ref.current;
  }

  const prevValue = usePrevious(crypt.priceUsd);




  useEffect(() => {
    if (prevValue !== crypt.priceUsd) {

      if (prevValue === undefined || prevValue === crypt.priceUsd) {
        setCls([])
      }
      else if (crypt.priceUsd > prevValue) {
        setCls(['increase']);
        const timeout = setTimeout(() => {
          setCls([])
          clearTimeout(timeout)
        }, 1000)
      }
      else if (crypt.priceUsd < prevValue) {
        setCls(['reduce']);
        const timeout = setTimeout(() => {
          setCls([])
          clearTimeout(timeout)
        }, 1000);
      }
    }
  }, [prevValue, crypt.priceUsd])

  return (
    <tr>
      <td>{crypt.name}</td>
      <td>{crypt.symbol}</td>
      <td
        className={cls.join('')}
      >
        {Number(crypt.priceUsd).toFixed(2)}
      </td>
      <td>{(Math.abs(Number(crypt.marketCapUsd)) / 1.0e+9).toFixed(2) + "B $"}</td>
      <td>{(Math.abs(Number(crypt.volumeUsd24Hr)) / 1.0e+9).toFixed(2) + "B $"}</td>
      <td className={crypt.changePercent24Hr > 0.0 ? "text-above" : "text-below"} >
        {Number(crypt.changePercent24Hr).toFixed(2) + "%"}
        <span className={crypt.changePercent24Hr > 0.0 ? "span-above" : "span-below"}></span>
      </td>
    </tr>
  )
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question