reactjs - canlı ziyaretçi sayacının sayfayı yenilemeden değişmesini sağla


Müşterim toplam ziyaretçi sayacı yapmak istiyor.

Toplam ziyaretçi sayacının kullanıcı sayfayı yenilemediğinde bile artmasını sağlamak mümkün mü? Böylece kullanıcılar sayfayı yenilemeden toplam ziyaretçi sayısının arttığını görebilir. Bunu gerçekleştirmek için ne eklemeliyim? Lütfen detaylı olarak açıklayın çünkü ben TypeScript'e yeniyim.

işte benim kodum

type visitortype={
  count: number;
}


const Footer = () => {
  const [visitor, setvisitor] = useState<visitortype>();

  useEffect(() => {
    fetch('https://count.cab/hit/ghG6Oirn0b')
    .then(response => response.json())
    .then(allvisitor=>  setvisitor(allvisitor))
    .catch(error => console.log(error));
  }, []);

 return (
    <GridItem
      w="100%"
      h={{ base: "80px", lg: "300px" }}
      colSpan={{ base: 8, lg: 4 }}
    >
      <VStack
        align={{ base: "center", lg: "stretch" }}
        marginTop={{ base: "0", lg: "60px" }}
        marginLeft={{ base: "0", lg: "50px" }}
      >
        <Box w={{ base: "100px", lg: "220px" }} paddingBottom={"10px"}>
          <Image src={imgLogoMd} alt="Logo" w="100%" />
          <HStack>
            <Text fontSize={{ base: "xs", lg: "md" }} textAlign={"justify"}>
              {visitor?.count} Visitor
            </Text>
          </HStack>
        </Box>
      </VStack>
    </GridItem>
  );

};

Cevap #1

Canlı veya canlıya yakın sayaç elde edebileceğiniz birkaç strateji vardır:

  • Sadece istediğiniz aralıklarla API'nizi sorgulayarak güncel istatistikleri alın. Uygulaması çok basit.
  • Uzun anketleme, muhtemelen ikinci olarak uygulanması en basit olan yöntem ama backend üzerinde değişiklikler gerektirir
  • Sunucu tarafı olayları kullan
  • Kütüphane aracılığıyla websockets kullanın, örneğin socket.io veya sockjs

Sadece ilk yöntem backend üzerinde herhangi bir değişiklik gerektirmez ve muhtemelen sizin durumunuz için yeterli olacaktır. Tek yapmanız gereken, bir API'yi tekrar tekrar sorgulamanıza izin verecek bir kanca eklemektir: useInterval

İşte böyle görünebilir

import {useEffect, useRef, useState} from 'react';

type CallbackType = (...args: any[]) => any;

// first you will need useInterval hook, you can implement it yourself or grab it from the lib. 
export function useInterval(callback: CallbackType, delay: number) { 
  const savedCallback = useRef<CallbackType | undefined>(); 
  useEffect(() => { 
    savedCallback.current = callback; 
  }, [callback]); 
  
  useEffect(() => { 
    function func() { 
      savedCallback.current?.(); 
    } 
    if (delay !== null) { 
      let id = setInterval(func, delay); 
      return () => clearInterval(id); 
    } 
  }, [delay]); 
}

// let's say we would like to get fresh stats every minute
const REFRESH_INTERVAL = 60 * 1000

const Footer = () => {
  const [visitor, setVisitor] = useState<visitortype>();

  useInterval(async () => {
    try {
      const response = await fetch('https://count.cab/hit/ghG6Oirn0b')
      const data = await response.json()
      setVisitor(data);
    } catch(error) {
      console.log(error);
    }
  }, REFRESH_INTERVAL);

 return (
    <GridItem
      w="100%"
      h={{ base: "80px", lg: "300px" }}
      colSpan={{ base: 8, lg: 4 }}
    >
      <VStack
        align={{ base: "center", lg: "stretch" }}
        marginTop={{ base: "0", lg: "60px" }}
        marginLeft={{ base: "0", lg: "50px" }}
      >
        <Box w={{ base: "100px", lg: "220px" }} paddingBottom={"10px"}>
          <Image src={imgLogoMd} alt="Logo" w="100%" />
          <HStack>
            <Text fontSize={{ base: "xs", lg: "md" }} textAlign={"justify"}>
              {visitor?.count} Visitor
            </Text>
          </HStack>
        </Box>
      </VStack>
    </GridItem>
  );

};

Cevap #2

Web istemci-sunucu mimarisi esas olarak yalnızca istemcilerin istek başlattığı ilkesine dayanmaktadır.

Bu nedenle, ziyaretçinin her seferinde manuel olarak işlem yapmasına gerek kalmadan düzenli bir güncelleme sağlamak için ana çözüm, belirli bir önceden belirlenmiş aralıkta programlı olarak yeni istekler başlatmaktır.

React'te burada örneğin react-use'ten useInterval kancasını kullanabilirsiniz:

import { useInterval } from 'react-use';

useInterval(
  () => {
    fetch('https://count.cab/hit/ghG6Oirn0b')
    .then(response => response.json())
    .then(allvisitor=>  setvisitor(allvisitor))
    .catch(error => console.log(error));
  },
  10_000 // Delay in milliseconds, e.g. here every 10 seconds
);

Artık, David'in cevabında bahsedildiği gibi WebSocket'ler ve Sunucu Olayları gibi, yalnızca orijinal istemci başlatmalı istek şemasından kaçmayı mümkün kılan istemci ve sunucu arasında "canlı" bir bağlantı kurmanın daha gelişmiş yolları vardır, ancak bu sunucuyu buna göre yapılandırmayı gerektirir.

İlgili makaleler