-1

Goal is to display a real time log that comes from an async function ( this func will return the last log ) and is updated each second. After that i want to accumulate the results on an array and if it get bigger than 5 i want to remove the first element.

Expected: A list of 5 items displayed on screen that is updated each second.

Results: Array is not accumulating above 2 items and the update is random and fast

code ->

const [logs, setLogs] = useState([])

const getLogs = async () => {

        const lastLog = await window.getAppLogs()

        if (logs.length > 5) {
            // here i tried this methods -> 
            // reduceLogs.shift()
            // reduceLogs.splice(0, 1)
          const reduceLogs = [...logs, lastLog ]
          delete reduceLogs[0]
          return setLogs(reduceLogs)
        }
        
        const test = [...logs, lastLog] // this line is not accumulating above 2
        setLogs(test)
}

useEffect(() => {
    setInterval(getLogs, 1000);
}, [])
brenoca
  • 1
  • 2

2 Answers2

0

Updating state in setinterval needs to use the => syntax. So it should be -

setLogs(prevState => [...prevState.slice(-4), lastLog])

Plus you need to clear the interval as well. I've made a demo to display last 5 users when they are updated every second (from api).

Edit intelligent-khorana-oeqcyt

export default function App() {
  const [users, setUsers] = useState([
    "michael",
    "jack",
  ]);

  const getUser = async () => {
    const response = await fetch("https://randomuser.me/api/?results=1");
    const user = await response.json();
    return user;
  };

  const getUsers = async () => {
    const user = await getUser();
    setUsers(prevState => [...prevState.slice(-4), user.results[0].name.first]);
  };

  useEffect(() => {
    const handle = setInterval(getUsers, 1000);
    return () => {
      clearInterval(handle);
    };
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {users.map((log) => (
        <div>{log}</div>
      ))}
    </div>
  );
}

Update: This should be your getLogs function, no if check, no return etc.

const getLogs = async () => {
  const lastLog = await window.getAppLogs()
  setLogs((prevState) => [...prevState.slice(-4), lastLog]);
}
A G
  • 21,087
  • 11
  • 87
  • 112
0

hey AG its almost working perfectly, updates are constant now and it is accumulating. But is still not reducing length of the array. Its like u show me:

const [logs, setLogs] = useState([])
const getLogs = async () => {
    
        const lastLog = await window.getAppLogs()
     
        if (logs.length > 4) {

            return setLogs((prevState) => [...prevState.slice(-4), lastLog])
        }

        setLogs((prevState) => [...prevState, lastLog])
}

useEffect(() => {
    const handle = setInterval(getLogs, 2500);
    return () => {
      clearInterval(handle);
    };
}, [])
brenoca
  • 1
  • 2