-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feedback from salvoravida #3
Comments
Originally, I wanted to emulate actions from the network.
Well, the reactive part I took is from "useTrackedState".
That's what I expect. React is throwing away intermediate screens.
I wouldn't disagree here. It's a behavior. I think most of apps do work without noticing it. |
But, according to Talk by Flarnie Marchan, it was a real problem in Facebook. The question is if this project is replicating the same issue. |
i have not seen all the video, but it seems that it comes out with incorrect state rendered, not tearing. Am i missing something? |
Yes, that is what I check by "check1". |
after some more investigation i see that reading store.state on render phase was the probelm, |
can you try with this temp build "@salvoravida/react-redux": "^7.1.4", |
I think the approach is good. It has to take care about store state updated during react rendering. That's technically possible either with useLayoutEffect which run in sync or something like use-subscription. This issue is not covered by my checks in this project, because it's more important than tearing and assumed to be solved. |
sorry i cannot understand, what issue are you talking about? |
Let me take some time to come up with an idea to check it, so that I can explain better with examples. |
🎉 "@salvoravida/react-redux": "^7.1.6"
|
Note: you should update your demo const _Counter = () => {
const count = useSelector(state => state.count);
syncBlock();
return <div className="count">{count}</div>;
};
_Counter.defaultProps={};
//https://github.com/facebook/react/issues/17318
//currently 2019.11.10 SimpleMemoCompnent is buggy on CM
const Counter=React.memo(_Counter); |
Wow, looks like you know how all things work. |
const _Counter = () => {
const count = useSubscription(React.useMemo(() => ({
getCurrentValue: () => store.getState().count,
subscribe: (callback) => {
return store.subscribe(callback);
},
}), []));
syncBlock();
return <div className="count">{count}</div>;
};
_Counter.defaultProps = {};
const Counter = React.memo(_Counter); now it's ok!
|
useSubscription is OK! React.memo in SimpleMemo version NO! 👯♂ |
So so so amazing!!! |
I confirmed this patch makes use-subscription's check4 to pass. diff --git a/src/use-subscription/index.js b/src/use-subscription/index.js
index 3bc6f4e..180ab62 100644
--- a/src/use-subscription/index.js
+++ b/src/use-subscription/index.js
@@ -21,7 +21,7 @@ const Counter = React.memo(() => {
}), []));
syncBlock();
return <div className="count">{count}</div>;
-});
+}, () => true);
const Main = () => {
const count = useSubscription(React.useMemo(() => ({ |
@samcooke98 You might want to try this workaround until it's resolved. (If you have props, use shallowEqual). |
Thanks for the tag. I've added a failing test to React here: facebook/react#17336 |
@salvoravida I added your fork and failing test case.
|
Have you change the test? |
Yes, look at the commit. fb5c61a |
yes i understand, i was already working on it. the problem is useRef. |
PASS tests/all_spec.js (12.425s) "@salvoravida/react-redux": "^7.1.8", |
That was quick! You eliminated the useRef? |
yes useRef is not enquequed so is not CM safe. on SelectedState NOT changed
on change in this way, reduxState is correctly enququed and React will discard updates with prevState=nextState. |
the only "problem" is this test: it('uses the latest selector', () => {
let selectorId = 0
let forceRender
const Comp = () => {
const [, f] = useReducer(c => c + 1, 0)
forceRender = f
const renderedSelectorId = selectorId++
const value = useSelector(() => renderedSelectorId)
renderedItems.push(value)
return <div />
}
rtl.render(
<ProviderMock store={store}>
<Comp />
</ProviderMock>
)
expect(renderedItems).toEqual([0])
rtl.act(forceRender)
expect(renderedItems).toEqual([0, 1])
rtl.act(() => {
store.dispatch({ type: '' })
})
expect(renderedItems).toEqual([0, 1])
rtl.act(forceRender)
expect(renderedItems).toEqual([0, 1, 2])
}) because React will render and discard the render. But i really think that this test is NOT ok. is it not safe upadate var on render, |
hum i cannot replicate what you say, to me it seems ok are you sure have update to 7.1.8 ? |
I try several times, but it's not easy to reproduce this error. It only happens rarely. Yeah, but it's reproducible. |
can you make a test? |
|
I don't think I can make an automated test for this. Let me try with other libs. |
Okay, I was able to reproduce it with Let's ignore this unless we find a better way to reproduce it. |
This is a nice hack, but it's uncertain if this works in the future, even if it's working now. BTW, as you are so powerful in this field, I would like have your opinion on my lib. |
hum state is propagate 2 times, one via listeners and one via Context, how does impact on performances? |
what do you think abot 'uses the latest selector' |
Yep. https://github.com/dai-shi/reactive-react-redux#benchmarks reduxjs/react-redux-benchmarks#26 |
great! why it is not rendered 2 times? one from listener callback and one from context change?O_O |
Because it's using changedBits=0 hack. Please read this summary: dai-shi/reactive-react-redux#29 |
It looks ok to me. Whether it's mutating in render is not important. It's just testing to read the latest selector (maybe from props. In that sense, there can be a better test, but what it tests would be the same.) |
i think that this test is not safe in CM. renders may be discarded. prevState=>prevStates seems to re-render but than scarted due to prevState=newState. useSubscription use this pattern. i think that this test will fails witn useSubscription too. |
hum and what about zombie child bug? with the hack you loos the benefit of top down context propagation. in this way it seems totally useless, is it just a shared mem ? am i missing something? |
It's the same as the stale props issue, right? Either my approach or the current react-redux v7 solves the stale props issue. (BTW the stale props issue is only applicable to
Yeah, my approach doesn't get the benefit of top-down context propagation much (not zero). It's basically the same as
No, I think you are on the right track. So, the difference between reactive-react-redux and react-redux is subtle. But, this little difference solves the CM tearing issue, because we read from a single react state (not redux store state) through context.
So, yes. It's just a shared mem, but this shared mem is managed by React. That's the point. |
@dai-shi new tests? yes i do not have yet time to look at, but i think we need streaming states that sometimes selector get and sometime no, while parent what to re-render for Others props, that modifie selector. This should be the worst case. have you tested @salvoravida/react-redux 7.1.9 |
Yeah, just finished. It was hard to make automated tests, whereas it was easy doing it by hand.
I'm not sure if I understand this. Could you elaborate it with examples when you have time? |
have you tested @salvoravida/react-redux 7.1.9 ? |
salvoravida-react-redux 7.1.9 that's great. as all of us expected branching in redux is not supported currently. but i'm thinking another test. we should have a test that for every reduxState Changes, This is the worst case. |
that's another point that should be better tested, localIncrement is fired from React internal button.onClick that is wrapped under Scheduler.runWithUserBlockingPpriority, that will force React to not do concurrent work. So localIncrement should be fired in a different way. |
Hm, I'm not following your suggestion. Are there two points? Please help me understand them... I know
Isn't it sufficient with the current |
@dai-shi I am not sure I understand the state branching issue. Can you point me to where eddyw explains it? |
@MrWolfZ In the thread starting from this comment: reduxjs/react-redux#1351 (comment) |
Closing this. Please open a new issue for further discussion. |
reduxjs/react-redux#1351 (comment)
@salvoravida gave some feedbacks. As far as I know you are the forth person who read this project carefully. Just an estimate.
The text was updated successfully, but these errors were encountered: