@@ -109,23 +109,30 @@ export function useInternalState<TData, TVariables extends OperationVariables>(
109
109
client : ApolloClient < any > ,
110
110
query : DocumentNode | TypedDocumentNode < TData , TVariables >
111
111
) : InternalState < TData , TVariables > {
112
- const stateRef = React . useRef < InternalState < TData , TVariables > > ( ) ;
113
- if (
114
- ! stateRef . current ||
115
- client !== stateRef . current . client ||
116
- query !== stateRef . current . query
117
- ) {
118
- stateRef . current = new InternalState ( client , query , stateRef . current ) ;
119
- }
120
- const state = stateRef . current ;
121
-
122
112
// By default, InternalState.prototype.forceUpdate is an empty function, but
123
113
// we replace it here (before anyone has had a chance to see this state yet)
124
114
// with a function that unconditionally forces an update, using the latest
125
- // setTick function. Updating this state by calling state.forceUpdate is the
126
- // only way we trigger React component updates (no other useState calls within
127
- // the InternalState class).
128
- state . forceUpdateState = React . useReducer ( ( tick ) => tick + 1 , 0 ) [ 1 ] ;
115
+ // setTick function. Updating this state by calling state.forceUpdate or the
116
+ // uSES notification callback are the only way we trigger React component updates.
117
+ const forceUpdateState = React . useReducer ( ( tick ) => tick + 1 , 0 ) [ 1 ] ;
118
+
119
+ function createInternalState ( previous ?: InternalState < TData , TVariables > ) {
120
+ return Object . assign ( new InternalState ( client , query , previous ) , {
121
+ forceUpdateState,
122
+ } ) ;
123
+ }
124
+
125
+ let [ state , updateState ] = React . useState ( createInternalState ) ;
126
+
127
+ if ( client !== state . client || query !== state . query ) {
128
+ // If the client or query have changed, we need to create a new InternalState.
129
+ // This will trigger a re-render with the new state, but it will also continue
130
+ // to run the current render function to completion.
131
+ // Since we sometimes trigger some side-effects in the render function, we
132
+ // re-assign `state` to the new state to ensure that those side-effects are
133
+ // triggered with the new state.
134
+ updateState ( ( state = createInternalState ( state ) ) ) ;
135
+ }
129
136
130
137
return state ;
131
138
}
@@ -511,7 +518,7 @@ class InternalState<TData, TVariables extends OperationVariables> {
511
518
private onError ( error : ApolloError ) { }
512
519
513
520
private observable ! : ObservableQuery < TData , TVariables > ;
514
- private obsQueryFields ! : Omit <
521
+ public obsQueryFields ! : Omit <
515
522
ObservableQueryFields < TData , TVariables > ,
516
523
"variables"
517
524
> ;
0 commit comments