Просмотр исходного кода

More work Context api example

Played around with context api, tried to get the wrapped component to rerender after global context
was updated - this is what I came up with.

Note: this commit makes the playground app use a newer js core as the js core which shipped with RN on Android
is missing javascript Proxy.

Closes #4517
Guy Carmeli 5 лет назад
Родитель
Сommit
dd41d48c36

+ 2
- 1
package.json Просмотреть файл

@@ -66,6 +66,7 @@
66 66
     "@types/react": "16.x.x",
67 67
     "@types/react-native": "0.57.7",
68 68
     "@types/react-test-renderer": "16.x.x",
69
+    "jsc-android": "236355.x.x",
69 70
     "detox": "9.0.6",
70 71
     "handlebars": "4.x.x",
71 72
     "jest": "23.x.x",
@@ -75,7 +76,7 @@
75 76
     "react-native-typescript-transformer": "^1.2.10",
76 77
     "react-native-view-overflow": "0.0.3",
77 78
     "react-redux": "5.x.x",
78
-    "react-test-renderer": "16.6.3",
79
+    "react-test-renderer": "16.6.1",
79 80
     "redux": "3.x.x",
80 81
     "remx": "2.x.x",
81 82
     "semver": "5.x.x",

+ 6
- 0
playground/android/app/build.gradle Просмотреть файл

@@ -54,6 +54,12 @@ configurations.all {
54 54
     }
55 55
 }
56 56
 
57
+configurations.all {
58
+    resolutionStrategy {
59
+        force 'org.webkit:android-jsc:r236355'
60
+    }
61
+}
62
+
57 63
 dependencies {
58 64
     implementation fileTree(dir: 'libs', include: ['*.jar'])
59 65
     implementation 'com.android.support:design:28.0.0'

+ 1
- 0
playground/android/build.gradle Просмотреть файл

@@ -27,5 +27,6 @@ allprojects {
27 27
         }
28 28
         maven { url 'https://jitpack.io' }
29 29
         maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
30
+        maven { url "$rootDir/../../node_modules/jsc-android/dist" }
30 31
     }
31 32
 }

+ 27
- 2
playground/src/context/index.js Просмотреть файл

@@ -1,7 +1,32 @@
1 1
 const React = require('react');
2
-const titleContext = React.createContext('Default title from Context');
2
+let ctx = {
3
+  title: 'Title from global context',
4
+  count: 0
5
+};
6
+
7
+const stateAwareContext = (component) =>
8
+  new Proxy(ctx, {
9
+    set: function (obj, prop, value) {
10
+      obj[prop] = value;
11
+      component.setState({ context: stateAwareContext(component) });
12
+      return true;
13
+    }
14
+  });
15
+
16
+const GlobalContext = React.createContext({});
17
+class ContextProvider extends React.Component {
18
+  state = {context :stateAwareContext(this)};
19
+  render() {
20
+    return (
21
+      <GlobalContext.Provider value={this.state.context}>
22
+        {this.props.children}
23
+      </GlobalContext.Provider>
24
+    );
25
+  }
26
+}
3 27
 
4 28
 module.exports = {
5
-  TitleContext: titleContext,
29
+  ContextProvider,
30
+  GlobalContext,
6 31
   Context: React.createContext('Default value from Context')
7 32
 }

+ 13
- 6
playground/src/screens/ContextScreen.js Просмотреть файл

@@ -1,7 +1,7 @@
1 1
 const React = require('react');
2
-const { View, Text } = require('react-native');
2
+const { View, Text, Button } = require('react-native');
3 3
 const testIDs = require('../testIDs');
4
-const { TitleContext, Context } = require('../context');
4
+const { GlobalContext, Context } = require('../context');
5 5
 
6 6
 class ContextScreen extends React.Component {
7 7
   static contextType = Context;
@@ -28,11 +28,18 @@ class ContextScreen extends React.Component {
28 28
         </View>
29 29
         <View style={{ flexDirection: 'row', alignItems: 'center' }}>
30 30
           <Text style={styles.h2}>Provider value: </Text>
31
-          <TitleContext.Consumer>
32
-            {title => (
33
-              <Text style={styles.h2} testID={testIDs.CENTERED_TEXT_HEADER}>{title}</Text>
31
+          <GlobalContext.Consumer>
32
+            {ctx => (
33
+              <Text style={styles.h2} testID={testIDs.CENTERED_TEXT_HEADER}>{ctx.title}</Text>
34 34
             )}
35
-          </TitleContext.Consumer>
35
+          </GlobalContext.Consumer>
36
+        </View>
37
+        <View>
38
+          <GlobalContext.Consumer>
39
+            {ctx => (
40
+              <Button title={`clicked ${ctx.count}`} onPress={() => ctx.count++}/>
41
+            )}
42
+          </GlobalContext.Consumer>
36 43
         </View>
37 44
       </View>
38 45
     );

+ 6
- 6
playground/src/screens/index.js Просмотреть файл

@@ -29,7 +29,7 @@ const KeyboardScreen = require('./KeyboardScreen');
29 29
 const BottomTabSideMenuScreen = require('./complexlayouts/BottomTabSideMenuScreen');
30 30
 const FlatListScreen = require('./FlatListScreen');
31 31
 const ContextScreen = require('./ContextScreen');
32
-const { TitleContext } = require('../context');
32
+const { ContextProvider } = require('../context');
33 33
 
34 34
 function registerScreens() {
35 35
   Navigation.registerComponent(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
@@ -40,12 +40,12 @@ function registerScreens() {
40 40
   Navigation.registerComponent(`navigation.playground.LifecycleScreen`, () => LifecycleScreen);
41 41
   Navigation.registerComponent(`navigation.playground.StaticLifecycleOverlay`, () => StaticLifecycleOverlay);
42 42
   Navigation.registerComponent(`navigation.playground.TextScreen`, () => TextScreen);
43
-  Navigation.registerComponent(`navigation.playground.PushedScreen`, () => PushedScreen);
44
-  Navigation.registerComponent('navigation.playground.ContextScreen', () => (props) => (
45
-    <TitleContext.Provider value={'Title from Provider'}>
43
+  Navigation.registerComponent('navigation.playground.PushedScreen', () => PushedScreen);
44
+  Navigation.registerComponent('navigation.playground.ContextScreen',() => (props) =>
45
+    <ContextProvider>
46 46
       <ContextScreen {...props} />
47
-    </TitleContext.Provider>
48
-  ), () => ContextScreen);
47
+    </ContextProvider>,
48
+    () => ContextScreen);
49 49
   Navigation.registerComponent(`navigation.playground.OptionsScreen`, () => OptionsScreen);
50 50
   Navigation.registerComponent(`navigation.playground.OrientationSelectScreen`, () => OrientationSelectScreen);
51 51
   Navigation.registerComponent(`navigation.playground.OrientationDetectScreen`, () => OrientationDetectScreen);