Cannot get new state if in conditional render ( really tricky )
WreewanMorhee opened this issue · comments
teaful: 0.10.0
node: v15.14.0
npm : 7.7.6
import { useEffect, useState } from 'react'
import createStore from 'teaful'
import './App.css'
import ErrorBoundary from './components/ErrorBoundary'
const initialStore = {
number: 0,
}
export const { useStore } = createStore(initialStore)
function App() {
const [show, set_show] = useState(false)
useEffect(() => {
set_show(true)
}, [])
return (
<ErrorBoundary>
<div className="App">
<AA />
<CC />
{/* {show && (
<>
<AA />
<CC />
</>
)} */}
</div>
</ErrorBoundary>
)
}
const AA = () => {
const [number] = useStore.number()
console.warn(number, 45678)
return number
}
const CC = () => {
const [number, set_number] = useStore.number()
if (!number) {
set_number((prev) => prev + 1)
}
return 'c'
}
export default App
works well works fine
BUT
if I put AA and CC into conditional render and other code just stay the same:
import { useEffect, useState } from 'react'
import createStore from 'teaful'
import './App.css'
import ErrorBoundary from './components/ErrorBoundary'
const initialStore = {
number: 0,
}
export const { useStore } = createStore(initialStore)
function App() {
const [show, set_show] = useState(false)
useEffect(() => {
set_show(true)
}, [])
return (
<ErrorBoundary>
<div className="App">
{/* <AA />
<CC /> */}
{show && (
<>
<AA />
<CC />
</>
)}
</div>
</ErrorBoundary>
)
}
const AA = () => {
const [number] = useStore.number()
console.warn(number, 45678)
return number
}
const CC = () => {
const [number, set_number] = useStore.number()
if (!number) {
set_number((prev) => prev + 1)
}
return 'c'
}
export default App
AA cannot get new number anymore
WHY !?
@WreewanMorhee It's nice to find tricky things that they should work properly. Thanks for the error, we will add it as failing test and try to correct it.
I imagine that happens something with the order of instructions, like:
CC
getnumber
as0
CC
subscribes tonumber
propertyAA
getnumber
as0
CC
update the property (component AA is not subscribed yet tonumber
)- All subscribed components to
number
property are rerendered. AA
subscribes tonumber
property
After researching I see that replacing the current store subscription implementation to useSyncExternalStore
it should fix this. So we will prioritize changing the subscription system, apart from the fact that it may further reduce the bundle size of the package 😊