Home > database >  useEffect doesn't fire in the beginning when dependency is empty array
useEffect doesn't fire in the beginning when dependency is empty array

Time:08-24

I'm learning react by coding, here i have strange behaviour which is first time happening. In my console i should be getting same values from state and from redux, but for some reason first one gives me 'books from state undefined' and second one 'books from redux: {roman: [},fantasy:[]}'. in my useEffect i have empty array, shouldnt it fire in the beginning when user comes to the page ?, why just one of them works and not other ?

  const [choosebook, setChoosebook] = useState<any>("");


const books = useSelector(
    (state: RootStateOrAny) => state.library.books
  );
  
  
   useEffect(() => {
    setChoosebook(books.book);
  }, []);
  
   console.log(
    "books from state: ", choosebook,
    "books from redux: ", books.book
  );

CodePudding user response:

I think the code looks okay. The problem comes from that the state is set correctly in the useEffect hook, but useEffect and useState runs asynchronously, so there is no guarantee that it will finish by the time the console.log runs.

You can try to wrap around the console.log line with another useEffect hook, which has the choosebook as a depedency.

const [choosebook, setChoosebook] = useState<any>("");


const books = useSelector(
    (state: RootStateOrAny) => state.library.books
  );
  
  
   useEffect(() => {
    setChoosebook(books.book);
  }, []);

  useEffect(() => {
   console.log(
    "books from state: ", choosebook,
    "books from redux: ", books.book
  );
  }, [choosebook]);

CodePudding user response:

useEffect is being called after a render.

First you see your console.log with choosebook being empty during the first render.

Only after that setChoosebook is being invoked inside the useEffect.

EDIT:

You can initialize the value of choosebook with the value you get from Redux:

const books = useSelector(
    (state: RootStateOrAny) => state.library.books
);
const [choosebook, setChoosebook] = useState<any>(books.book);
  • Related