preactjs / preact

⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Home Page:https://preactjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

useSelector hook stops being called under certain conditions since preact 10.19.4

yy0931 opened this issue · comments

  • Check if updating to the latest Preact version resolves the issue

The useSelector hook in react-redux has stopped working under certain conditions since Preact 10.19.4. Below is a simplified code snippet to reproduce the issue, where the page should display a value incremented every 250 ms, but it stops at 1. The code works correctly on React. Using the Preact version from the pull request #4284 did not fix it.

import { configureStore, createSlice } from '@reduxjs/toolkit'
import { render } from "preact"
import { useEffect, useLayoutEffect } from "preact/hooks"
import { Provider, useDispatch, useSelector } from 'react-redux'

const slice = createSlice({
    name: "counter",
    initialState: {
        a: 0,
        b: 0,
    },
    reducers: {
        incrementA: (state) => { state.a++ },
        incrementB: (state) => { state.b++ },
    },
})
const store = configureStore({
    reducer: {
        counter: slice.reducer,
    },
})

type State = ReturnType<typeof store.getState>

const Parent = () => {
    const dispatch = useDispatch()

    // Increment `a` every 250ms.
    useEffect(() => {
        const timer = setInterval(() => {
            dispatch(slice.actions.incrementA())
        }, 250)
        return () => clearInterval(timer)
    }, [dispatch])

    // Reference the value of `a` after useEffect.
    useSelector((state: State) => state.counter.a)

    return <Child />
}

const Child = () => {
    const dispatch = useDispatch()

    const a = useSelector((state: State) => state.counter.a)

    // Increment `b` immediately after `a` is incremented.
    useLayoutEffect(() => {
        dispatch(slice.actions.incrementB())
    }, [a, dispatch])

    // Reference the value of `a` after useLayoutEffect. (This was originally called via another hook.)
    useSelector((state: State) => state.counter.a)

    return <>{a}</>
}

render(
    <Provider store={store}>
        <Parent />
    </Provider>,
    document.body
)

Here is the GitHub repository containing both Preact and React versions: https://github.com/yy0931/preact-store-issue

Steps to reproduce the behavior:

  1.  git clone https://github.com/yy0931/preact-store-issue
     cd preact-store-issue
     npm i
     cd preact
     npx vite
  2. See the number not being incremented on a browser

Expected behavior: The value should increment.

I wonder if it's related to #4234

I wonder if it's related to #4234

@JoviDeCroock That would explain the issues with floating-ui where the hooks are not getting called or receiving outdated element positions. This appeared in version 10.19.4 or preact. Version 10.19.3 works fine.

Same problem here: I've got a class component whose render method is not called after a setState. The bug appeared in 10.19.4, downgrading to 10.19.3 fixes the problem.