UNPKG

3.4 kBTypeScriptView Raw
1declare var require: any;
2import React, { useState } from 'react';
3import ExecutionEnvironment from 'exenv';
4
5const IsomorphicStateContext = React.createContext({});
6
7interface IsomorphicStateProps {
8 preloadedState?: any,
9 setServerValue?: (id: string, value: any) => any,
10 children: any
11}
12
13const AttachIsomorphicState = (props: IsomorphicStateProps) => {
14
15 if (ExecutionEnvironment.canUseDOM) {
16
17 //at the client, get the value from the preloaded state
18 return <IsomorphicStateContext.Provider value={{
19 preloadedState: props.preloadedState
20 }}>{props.children}</IsomorphicStateContext.Provider>
21
22 } else {
23
24 //at the server, we provide a callback function that sets the preloadedState
25 return <IsomorphicStateContext.Provider value={{
26 setServerValue: props.setServerValue,
27 preloadedState: props.preloadedState
28 }}>{props.children}</IsomorphicStateContext.Provider>
29 }
30
31
32
33};
34
35export function withIsomorphicState(Component) {
36
37 return function WrapperComponent(props) {
38
39 return (
40 <IsomorphicStateContext.Consumer>
41 {(value: any) => {
42
43 //console.log("IsomorphicStateContext preloadedState: ", value.preloadedState);
44
45 if (ExecutionEnvironment.canUseDOM) {
46
47
48 //const [clientValue, clientSetter] = useState(value);
49 // we ignore the clientProps...but we take the props from the preloadedState!
50 return <Component {...props} useIsomorphicState={(id, initialValue) => useState( value.preloadedState? value.preloadedState[id]:undefined)} />
51
52 } else {
53
54 const useServerState = (id, intialValue) => {
55 //console.log("useServerState: ", id, " -> ", intialValue);
56 if (value.setServerValue) {
57 value.setServerValue(
58 id,
59 value.preloadedState && value.preloadedState[id] ? value.preloadedState[id]: intialValue,
60 true);
61 };
62
63 const [serverValue, setValue] = useState(
64 value.preloadedState && value.preloadedState[id] ? value.preloadedState[id]:intialValue
65 );
66
67 const setServerValue = (newValue) => {
68
69 // "value" is the function "setServerValue" from the Context
70 if (value.setServerValue) {
71 value.setServerValue(id, newValue);
72 }
73
74 // the normal hook setter
75 setValue(newValue);
76 }
77
78 //console.log("serverValue: ", serverValue);
79 return [serverValue, setServerValue];
80 }
81
82 // when on the server, we use the initial value as provided
83 return <Component {...props} useIsomorphicState={useServerState} />
84 }
85
86
87 }}
88 </IsomorphicStateContext.Consumer>
89 );
90 };
91}
92
93export default AttachIsomorphicState;
94
95
96
97