Skip to content

Commit 4a4147b

Browse files
committed
Skeleton for store
1 parent 4a45ba9 commit 4a4147b

15 files changed

+128
-3
lines changed

packages/react-reconciler/src/ReactFiberHooks.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
Thenable,
1515
RejectedThenable,
1616
Awaited,
17+
ReactStore,
1718
} from 'shared/ReactTypes';
1819
import type {
1920
Fiber,
@@ -44,10 +45,12 @@ import {
4445
enableNoCloningMemoCache,
4546
enableViewTransition,
4647
enableGestureTransition,
48+
enableStore,
4749
} from 'shared/ReactFeatureFlags';
4850
import {
4951
REACT_CONTEXT_TYPE,
5052
REACT_MEMO_CACHE_SENTINEL,
53+
REACT_STORE_TYPE,
5154
} from 'shared/ReactSymbols';
5255

5356
import {
@@ -1145,6 +1148,10 @@ function useThenable<T>(thenable: Thenable<T>): T {
11451148
return result;
11461149
}
11471150

1151+
function useStore<T>(store: ReactStore<T>): T {
1152+
return store._current;
1153+
}
1154+
11481155
function use<T>(usable: Usable<T>): T {
11491156
if (usable !== null && typeof usable === 'object') {
11501157
// $FlowFixMe[method-unbinding]
@@ -1156,6 +1163,12 @@ function use<T>(usable: Usable<T>): T {
11561163
const context: ReactContext<T> = (usable: any);
11571164
return readContext(context);
11581165
}
1166+
if (enableStore) {
1167+
if (usable.$$typeof === REACT_STORE_TYPE) {
1168+
const store: ReactStore<T> = (usable: any);
1169+
return useStore(store);
1170+
}
1171+
}
11591172
}
11601173

11611174
// eslint-disable-next-line react-internal/safe-string-coercion
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @emails react-core
8+
*/
9+
'use strict';
10+
11+
let React;
12+
let ReactNoop;
13+
let Scheduler;
14+
let act;
15+
let use;
16+
let assertLog;
17+
let createStore;
18+
19+
describe('ReactUse', () => {
20+
beforeEach(() => {
21+
jest.resetModules();
22+
23+
React = require('react');
24+
ReactNoop = require('react-noop-renderer');
25+
Scheduler = require('scheduler');
26+
act = require('internal-test-utils').act;
27+
use = React.use;
28+
createStore = React.unstable_createStore;
29+
30+
const InternalTestUtils = require('internal-test-utils');
31+
assertLog = InternalTestUtils.assertLog;
32+
});
33+
34+
// @gate enableStore
35+
it('should read the current value', async () => {
36+
const store = createStore(1);
37+
38+
function App() {
39+
const value = use(store);
40+
Scheduler.log(value);
41+
return <span>{value}</span>;
42+
}
43+
44+
const root = ReactNoop.createRoot();
45+
await act(() => {
46+
root.render(<App />);
47+
});
48+
assertLog([1]);
49+
expect(root).toMatchRenderedOutput(<span>1</span>);
50+
});
51+
});

packages/react/index.fb.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
* @flow
88
*/
99

10-
import {captureOwnerStack as captureOwnerStackImpl} from './src/ReactClient';
10+
import {
11+
captureOwnerStack as captureOwnerStackImpl,
12+
unstable_createStore as createStore,
13+
} from './src/ReactClient';
14+
import {enableStore} from 'shared/ReactFeatureFlags';
1115

1216
export {
1317
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
@@ -76,4 +80,9 @@ if (__DEV__) {
7680
captureOwnerStack = captureOwnerStackImpl;
7781
}
7882

79-
export {captureOwnerStack};
83+
let unstable_createStore: typeof createStore;
84+
if (enableStore) {
85+
unstable_createStore = createStore;
86+
}
87+
88+
export {captureOwnerStack, unstable_createStore};

packages/react/src/ReactClient.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
isValidElement,
3131
} from './jsx/ReactJSXElement';
3232
import {createContext} from './ReactContext';
33+
import {createStore} from './ReactStore';
3334
import {lazy} from './ReactLazy';
3435
import {forwardRef} from './ReactForwardRef';
3536
import {memo} from './ReactMemo';
@@ -128,6 +129,8 @@ export {
128129
addTransitionType as unstable_addTransitionType,
129130
// enableGestureTransition
130131
startGestureTransition as unstable_startGestureTransition,
132+
// enableStore
133+
createStore as unstable_createStore,
131134
// DEV-only
132135
useId,
133136
act,

packages/react/src/ReactStore.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {ReactStore} from 'shared/ReactTypes';
11+
import {REACT_STORE_TYPE} from 'shared/ReactSymbols';
12+
import {enableStore} from 'shared/ReactFeatureFlags';
13+
14+
export function createStore<T>(
15+
defaultValue: T,
16+
reducer?: (T, mixed) => T,
17+
): ReactStore<T> {
18+
if (!enableStore) {
19+
throw new Error('Not implemented.');
20+
}
21+
22+
const store: ReactStore<T> = {
23+
$$typeof: REACT_STORE_TYPE,
24+
25+
_current: defaultValue,
26+
_sync: defaultValue,
27+
_transition: defaultValue,
28+
};
29+
30+
return store;
31+
}

packages/shared/ReactFeatureFlags.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,5 @@ export const enableUpdaterTracking = __PROFILE__;
270270
export const enableDO_NOT_USE_disableStrictPassiveEffect = false;
271271

272272
export const ownerStackLimit = 1e4;
273+
274+
export const enableStore = false;

packages/shared/ReactSymbols.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export const REACT_VIEW_TRANSITION_TYPE: symbol = Symbol.for(
5151
'react.view_transition',
5252
);
5353

54+
export const REACT_STORE_TYPE: symbol = Symbol.for('react.store');
55+
5456
const MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
5557
const FAUX_ITERATOR_SYMBOL = '@@iterator';
5658

packages/shared/ReactTypes.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ export type ReactContext<T> = {
6464
displayName?: string,
6565
};
6666

67+
export type ReactStore<T> = {
68+
$$typeof: symbol,
69+
_current: T,
70+
_sync: T,
71+
_transition: T,
72+
};
73+
6774
export type ReactPortal = {
6875
$$typeof: symbol | number,
6976
key: null | string,
@@ -141,7 +148,7 @@ export type StartTransitionOptions = {
141148
name?: string,
142149
};
143150

144-
export type Usable<T> = Thenable<T> | ReactContext<T>;
151+
export type Usable<T> = Thenable<T> | ReactContext<T> | ReactStore<T>;
145152

146153
export type ReactCustomFormAction = {
147154
name?: string,

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export const enableSrcObject = false;
8888
export const enableHydrationChangeEvent = true;
8989
export const enableDefaultTransitionIndicator = false;
9090
export const ownerStackLimit = 1e4;
91+
export const enableStore = false;
9192

9293
// Flow magic to verify the exports of this file match the original version.
9394
((((null: any): ExportsType): FeatureFlagsType): ExportsType);

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ export const enableProfilerTimer = __PROFILE__;
8686
export const enableProfilerCommitHooks = __PROFILE__;
8787
export const enableProfilerNestedUpdatePhase = __PROFILE__;
8888
export const enableUpdaterTracking = __PROFILE__;
89+
export const enableStore = false;
8990

9091
// Flow magic to verify the exports of this file match the original version.
9192
((((null: any): ExportsType): FeatureFlagsType): ExportsType);

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export const enableReactTestRendererWarning = true;
9696
export const disableDefaultPropsExceptForClasses = true;
9797

9898
export const enableObjectFiber = false;
99+
export const enableStore = false;
99100

100101
// Flow magic to verify the exports of this file match the original version.
101102
((((null: any): ExportsType): FeatureFlagsType): ExportsType);

packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export const enableHydrationChangeEvent = false;
7676
export const enableDefaultTransitionIndicator = false;
7777
export const enableFragmentRefs = false;
7878
export const ownerStackLimit = 1e4;
79+
export const enableStore = false;
7980

8081
// Flow magic to verify the exports of this file match the original version.
8182
((((null: any): ExportsType): FeatureFlagsType): ExportsType);

packages/shared/forks/ReactFeatureFlags.test-renderer.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export const enableDefaultTransitionIndicator = false;
9191

9292
export const enableFragmentRefs = false;
9393
export const ownerStackLimit = 1e4;
94+
export const enableStore = false;
9495

9596
// Flow magic to verify the exports of this file match the original version.
9697
((((null: any): ExportsType): FeatureFlagsType): ExportsType);

packages/shared/forks/ReactFeatureFlags.www-dynamic.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export const enableViewTransition = __VARIANT__;
4040
export const enableComponentPerformanceTrack = __VARIANT__;
4141
export const enableScrollEndPolyfill = __VARIANT__;
4242
export const enableFragmentRefs = __VARIANT__;
43+
export const enableStore = __VARIANT__;
4344

4445
// TODO: These flags are hard-coded to the default values used in open source.
4546
// Update the tests so that they pass in either mode, then set these

packages/shared/forks/ReactFeatureFlags.www.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const {
3838
enableComponentPerformanceTrack,
3939
enableScrollEndPolyfill,
4040
enableFragmentRefs,
41+
enableStore,
4142
} = dynamicFeatureFlags;
4243

4344
// On WWW, __EXPERIMENTAL__ is used for a new modern build.

0 commit comments

Comments
 (0)