Yomguithereal / react-blessed

A react renderer for blessed.
MIT License
4.45k stars 177 forks source link

useEffect hook with empty dependency array called twice #111

Open paaatrick opened 4 years ago

paaatrick commented 4 years ago

First, wonderful library; thanks for your work on it.

If I have a component with a useEffect hook with an empty dependency array I would expect the callback function to be called once. However if the callback function calls a state updating function (i.e. one returned by useState or the dispatch function returned by useReducer) the callback is called twice. Here is an example:

import React, { useEffect, useState } from 'react';
import blessed from 'blessed';
import { render } from 'react-blessed';

const Test = () => {
  const [count, setCount] = useState(0);
  useEffect(() => {
    setCount(count => count + 1);
  }, []);
  return <element>{count}</element>;
};

const screen = blessed.screen({
  autoPadding: true,
  smartCSR: true,
  title: 'test'
});

screen.key(['escape', 'q', 'C-c'], () => {
  return process.exit(0);
});

render(
  <Test />,
  screen
);

I would expect the Test component to render 1, but instead it renders 2. The equivalent example using the react-dom renderer results in 1 being displayed (https://codesandbox.io/s/brave-grass-wik3s?file=/src/App.js).

This is the simplest example I could make to reproduce the problem. The context for this is I wanted to use useEffect to have a component make an HTTP request once on mount and store the results in state, but I kept seeing two HTTP requests being made.

Yomguithereal commented 3 years ago

Hello @paaatrick. Sorry for the late response but I did not find much time to investigate this issue. Would you be willing to try and peak under the hood to find what could cause this?

viktor-podzigun commented 3 years ago

FYI: useLayoutEffect works just fine, so for time being I use it instead of useEffect. Could be some issue related to scheduling.