Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

159
Views
React Components "flickers" on load, since state gets overriden

I work on a todo app with React and things become clearer, but I struggle to undersand the "lifecycle". In VueJS I know a ComponentDidMount() hook, which would help me to solve this issue if I guess, but in React I can´t find it out.

I have an array of todos like this: const todos = [{description: "walk dog", done: false}]

This is the initial state of my app:

const [alltodos, handleTodos] = useState([]);

On load I use this useEffect hook to get data from localStorage.

  useEffect(() => {
    const items = localStorage.getItem("todos");
    const parsed = JSON.parse(items);
    handleTodos(parsed);
  }, []);

I count my todos with this function:

  const countTodos = () => {
    const donetodos = alltodos.filter((item) => {
      return !item.done;
    });

    countOpen(donetodos.length);
  };

I update the count if a dependency changes:

  useEffect(() => {
    countTodos();
    localStorage.setItem("todos", JSON.stringify(alltodos));
  }, [alltodos]);

So what happens is that the counter starts with 0 and than "flickers" for a milisecond before it shows the number of todos which I get from localstorage.

Is there a way to prevent that behaviour? As far as I know the component gets rendered FIRST and then the useEffect hook gets triggered. How I render my component AFTER the data is pulled from localstorage?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

The best way to do this would be with a lazy initial state. Also, cleaning up the variables and using a standardized [variable, setVariable] will save you headache debugging in the future.

const [alltodos, setAlltodos] = useState(() => {
    const items = localStorage.getItem("todos");
    const parsed = JSON.parse(items);
    return parsed || "";
});
about 4 years ago · Juan Pablo Isaza Report

0

Initialize the allTodos state with null. As long as this state is null, render a notification or just return null to render nothing.

You can calculate the open todos count directly from the current alltodos state, without the need of useEffect.

const [alltodos, handleTodos] = useState(null);

useEffect(() => {
  const items = localStorage.getItem("todos");
  const parsed = items ? JSON.parse(items) : [];
  handleTodos(parsed);
}, []);

useEffect(() => {
  localStorage.setItem("todos", JSON.stringify(alltodos));
}, [alltodos]);

if(alltodos === null) return 'Loading todos list';

// this is derived from state, so you don't have to create a state for it
const openTodosCount = alltodos.reduce((acc, o) => acc + !o.done, 0);
about 4 years ago · Juan Pablo Isaza Report

0

The fastest way would be to add new state that would be responsible for loading. For example

const [isLoading, setIsLoading] = useState(true);

set it initially on true and then after you do all your calculations change it to false.

Then you can depend on that state and show div with a text "Loading" or anything else but when isLoading would go to false it will show component elements.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!