From 7c64cd7d8256c768775c17e19bc53b650a6293ce Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Wed, 7 Aug 2019 02:33:20 +0000 Subject: [PATCH 1/4] fix: Refactor code from componentWillReceiveProps (#205) componentWillReceiveProps is deprecated and will be completely removed in react 17. --- src/TableView.js | 223 +++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 116 deletions(-) diff --git a/src/TableView.js b/src/TableView.js index 0d49075..ac3bdf2 100644 --- a/src/TableView.js +++ b/src/TableView.js @@ -43,6 +43,78 @@ const FontWeight = PropTypes.oneOf([ ]); const FontStyle = PropTypes.oneOf(['italic', 'normal', 'oblique']); +// Translate TableView prop and children into stuff that RNTableView understands. +function stateFromProps(props) { + const sections = []; + const additionalItems = []; + const children = []; + + // iterate over sections + React.Children.forEach(props.children, (section, index) => { + const items = []; + let count = 0; + + if (section && section.type === TableViewSection) { + let customCells = false; + + React.Children.forEach(section.props.children, (child, itemIndex) => { + const el = {}; + extend(el, section.props); + extend(el, child.props); + + if (el.children) { + el.label = el.children; + } + + if (el.image && typeof el.image === 'number') { + el.image = resolveAssetSource(el.image); + } + + count++; + items.push(el); + + if (child.type === TableViewCell) { + customCells = true; + count++; + + const element = React.cloneElement(child, { + key: `${index} ${itemIndex}`, + section: index, + row: itemIndex, + }); + children.push(element); + } + }); + + sections.push({ + customCells, + label: section.props.label, + footerLabel: section.props.footerLabel, + footerHeight: section.props.footerHeight, + headerHeight: section.props.headerHeight, + items, + count, + }); + } else if (section && section.type === TableViewItem) { + const el = extend({}, section.props); + + if (!el.label) { + el.label = el.children; + } + + additionalItems.push(el); + } else if (section) { + children.push(section); + } + }); + + return { + sections, + additionalItems, + children, + }; +} + class TableView extends React.Component { static propTypes = { onPress: PropTypes.func, @@ -167,100 +239,25 @@ class TableView extends React.Component { constructor(props) { super(props); - this.state = this._stateFromProps(props); + this.state = stateFromProps(props); } - componentWillReceiveProps(nextProps) { - const state = this._stateFromProps(nextProps); - this.setState(state); - - if (this.props.refreshing === false && nextProps.refreshing) { + componentDidUpdate(prevProps) { + if (prevProps.refreshing === false && this.props.refreshing) { NativeModules.RNTableViewManager.startRefreshing( findNodeHandle(this.tableView) ); } - if (this.props.refreshing && !nextProps.refreshing) { + if (prevProps.refreshing && !this.props.refreshing) { NativeModules.RNTableViewManager.stopRefreshing( findNodeHandle(this.tableView) ); } } - // Translate TableView prop and children into stuff that RNTableView understands. - _stateFromProps(props) { - const sections = []; - const additionalItems = []; - const children = []; - const { json } = props; - - // iterate over sections - React.Children.forEach(props.children, (section, index) => { - const items = []; - let count = 0; - - if (section && section.type === TableViewSection) { - let customCells = false; - - React.Children.forEach(section.props.children, (child, itemIndex) => { - const el = {}; - extend(el, section.props); - extend(el, child.props); - - if (el.children) { - el.label = el.children; - } - - if (el.image && typeof el.image === 'number') { - el.image = resolveAssetSource(el.image); - } - - count++; - items.push(el); - - if (child.type === TableViewCell) { - customCells = true; - count++; - - const element = React.cloneElement(child, { - key: `${index} ${itemIndex}`, - section: index, - row: itemIndex, - }); - children.push(element); - } - }); - - sections.push({ - customCells, - label: section.props.label, - footerLabel: section.props.footerLabel, - footerHeight: section.props.footerHeight, - headerHeight: section.props.headerHeight, - items, - count, - }); - } else if (section && section.type === TableViewItem) { - const el = extend({}, section.props); - - if (!el.label) { - el.label = el.children; - } - - additionalItems.push(el); - } else if (section) { - children.push(section); - } - }); - - this.sections = sections; - - return { - sections, - additionalItems, - children, - json, - }; + static getDerivedStateFromProps(props) { + return stateFromProps(props); } scrollTo(x, y, animated) { @@ -288,16 +285,16 @@ class TableView extends React.Component { _onPress(event) { const data = event.nativeEvent; + const { sections } = this.state; + if ( - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex] && - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex].onPress + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex] && + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex].onPress ) { - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex].onPress( - data - ); + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex].onPress(data); } this.props.onPress(data); @@ -306,13 +303,13 @@ class TableView extends React.Component { _onAccessoryPress(event) { const data = event.nativeEvent; + const { sections } = this.state; this.props.onAccessoryPress(data); - if (this.sections) { - const pressedItem = this.sections[data.accessorySection].items[ - data.accessoryIndex - ]; + if (sections) { + const pressedItem = + sections[data.accessorySection].items[data.accessoryIndex]; pressedItem.onAccessoryPress && pressedItem.onAccessoryPress(data); } @@ -322,17 +319,16 @@ class TableView extends React.Component { _onChange(event) { const data = event.nativeEvent; + const { sections } = this.state; if ( - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex] && - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex].onChange + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex] && + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex].onChange ) { - this.sections[data.selectedSection] && - this.sections[data.selectedSection].items[data.selectedIndex].onChange( - data - ); + sections[data.selectedSection] && + sections[data.selectedSection].items[data.selectedIndex].onChange(data); } this.props.onChange(data); @@ -341,13 +337,14 @@ class TableView extends React.Component { _onWillDisplayCell(event) { const data = event.nativeEvent; + const { sections } = this.state; if ( - this.sections[data.section] && - this.sections[data.section].items[data.row] && - this.sections[data.section].items[data.row].onWillDisplayCell + sections[data.section] && + sections[data.section].items[data.row] && + sections[data.section].items[data.row].onWillDisplayCell ) { - this.sections[data.section].items[data.row].onWillDisplayCell(data); + sections[data.section].items[data.row].onWillDisplayCell(data); } this.props.onWillDisplayCell(data); @@ -356,13 +353,14 @@ class TableView extends React.Component { _onEndDisplayingCell(event) { const data = event.nativeEvent; + const { sections } = this.state; if ( - this.sections[data.section] && - this.sections[data.section].items[data.row] && - this.sections[data.section].items[data.row].onEndDisplayingCell + sections[data.section] && + sections[data.section].items[data.row] && + sections[data.section].items[data.row].onEndDisplayingCell ) { - this.sections[data.section].items[data.row].onEndDisplayingCell(data); + sections[data.section].items[data.row].onEndDisplayingCell(data); } this.props.onEndDisplayingCell(data); @@ -376,17 +374,10 @@ class TableView extends React.Component { ref={ref => { this.tableView = ref; }} - style={this.props.style} sections={this.state.sections} additionalItems={this.state.additionalItems} - tableViewStyle={this.props.tableViewStyle} - tableViewCellStyle={this.props.tableViewCellStyle} - tableViewCellEditingStyle={this.props.tableViewCellEditingStyle} - separatorStyle={this.props.separatorStyle} scrollIndicatorInsets={this.props.contentInset} - alwaysBounceVertical={this.props.alwaysBounceVertical} {...this.props} - json={this.state.json} onScroll={(...args) => this._onScroll(...args)} onPress={(...args) => this._onPress(...args)} onAccessoryPress={(...args) => this._onAccessoryPress(...args)} From c4ba4cc2f13e45fff0addfa29af4716b2ebb6461 Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Tue, 6 Aug 2019 22:45:12 -0400 Subject: [PATCH 2/4] feat: Update react navigation on example app --- example/android/app/build.gradle | 1 + .../java/com/tableviewdemo/MainActivity.java | 13 +++++++++ .../com/tableviewdemo/MainApplication.java | 2 ++ example/android/settings.gradle | 2 ++ .../TableViewDemo.xcodeproj/project.pbxproj | 29 ++++++++++++++++++- example/package.json | 3 +- example/yarn.lock | 13 ++++++--- 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 83cd483..7d2808e 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -138,6 +138,7 @@ android { } dependencies { + implementation project(':react-native-reanimated') implementation project(':react-native-gesture-handler') implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" diff --git a/example/android/app/src/main/java/com/tableviewdemo/MainActivity.java b/example/android/app/src/main/java/com/tableviewdemo/MainActivity.java index 60c6a05..d82922e 100644 --- a/example/android/app/src/main/java/com/tableviewdemo/MainActivity.java +++ b/example/android/app/src/main/java/com/tableviewdemo/MainActivity.java @@ -1,6 +1,9 @@ package com.tableviewdemo; import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; +import com.facebook.react.ReactRootView; +import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; public class MainActivity extends ReactActivity { @@ -12,4 +15,14 @@ public class MainActivity extends ReactActivity { protected String getMainComponentName() { return "TableViewDemo"; } + + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegate(this, getMainComponentName()) { + @Override + protected ReactRootView createRootView() { + return new RNGestureHandlerEnabledRootView(MainActivity.this); + } + }; + } } diff --git a/example/android/app/src/main/java/com/tableviewdemo/MainApplication.java b/example/android/app/src/main/java/com/tableviewdemo/MainApplication.java index 3436e47..c82da77 100644 --- a/example/android/app/src/main/java/com/tableviewdemo/MainApplication.java +++ b/example/android/app/src/main/java/com/tableviewdemo/MainApplication.java @@ -3,6 +3,7 @@ import android.app.Application; import com.facebook.react.ReactApplication; +import com.swmansion.reanimated.ReanimatedPackage; import com.swmansion.gesturehandler.react.RNGestureHandlerPackage; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; @@ -24,6 +25,7 @@ public boolean getUseDeveloperSupport() { protected List getPackages() { return Arrays.asList( new MainReactPackage(), + new ReanimatedPackage(), new RNGestureHandlerPackage() ); } diff --git a/example/android/settings.gradle b/example/android/settings.gradle index d1b6dfe..9684d07 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,4 +1,6 @@ rootProject.name = 'TableViewDemo' +include ':react-native-reanimated' +project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android') include ':react-native-gesture-handler' project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android') diff --git a/example/ios/TableViewDemo.xcodeproj/project.pbxproj b/example/ios/TableViewDemo.xcodeproj/project.pbxproj index acd754b..1585066 100644 --- a/example/ios/TableViewDemo.xcodeproj/project.pbxproj +++ b/example/ios/TableViewDemo.xcodeproj/project.pbxproj @@ -5,7 +5,6 @@ }; objectVersion = 46; objects = { - /* Begin PBXBuildFile section */ 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; @@ -44,6 +43,8 @@ DD2510CA1A414BE49C49BA99 /* libRNTableView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C235EA15AC0845A9BF9BBD05 /* libRNTableView.a */; }; ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED297162215061F000B7C4FE /* JavaScriptCore.framework */; }; ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; }; + 95AFB2FD224842F6BA9FD783 /* libRNReanimated.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A5C64E19BFC74D85AB6986AD /* libRNReanimated.a */; }; + 4AD036883BD6449584E7B380 /* libRNReanimated-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FC810FCC3B2F43BC9516842A /* libRNReanimated-tvOS.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -378,6 +379,9 @@ EB9353B6ACA54416963EA1E5 /* RNTableView.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNTableView.xcodeproj; path = "../node_modules/react-native-tableview/RNTableView.xcodeproj"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; + 2EF53D72C8B446C4A300FBC6 /* RNReanimated.xcodeproj */ = {isa = PBXFileReference; name = "RNReanimated.xcodeproj"; path = "../node_modules/react-native-reanimated/ios/RNReanimated.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; + A5C64E19BFC74D85AB6986AD /* libRNReanimated.a */ = {isa = PBXFileReference; name = "libRNReanimated.a"; path = "libRNReanimated.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; + FC810FCC3B2F43BC9516842A /* libRNReanimated-tvOS.a */ = {isa = PBXFileReference; name = "libRNReanimated-tvOS.a"; path = "libRNReanimated-tvOS.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -408,6 +412,7 @@ 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, DD2510CA1A414BE49C49BA99 /* libRNTableView.a in Frameworks */, D1BF78E1D34643189115AF19 /* libRNGestureHandler.a in Frameworks */, + 95AFB2FD224842F6BA9FD783 /* libRNReanimated.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -425,6 +430,7 @@ 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */, 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */, 030A481EB7B34BBAA3FC26EE /* libRNGestureHandler-tvOS.a in Frameworks */, + 4AD036883BD6449584E7B380 /* libRNReanimated-tvOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -628,6 +634,7 @@ 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, EB9353B6ACA54416963EA1E5 /* RNTableView.xcodeproj */, 036FDCC3112D4CB186BD3FAD /* RNGestureHandler.xcodeproj */, + 2EF53D72C8B446C4A300FBC6 /* RNReanimated.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -1279,6 +1286,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = TableViewDemoTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1288,6 +1296,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1308,6 +1318,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = TableViewDemoTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1317,6 +1328,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1338,6 +1351,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = TableViewDemo/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1361,6 +1375,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = TableViewDemo/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1391,6 +1406,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = "TableViewDemo-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1399,6 +1415,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1428,6 +1446,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = "TableViewDemo-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1436,6 +1455,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1464,6 +1485,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = "TableViewDemo-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1472,6 +1494,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", @@ -1500,6 +1524,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/react-native-tableview/RNTableView", "$(SRCROOT)/../node_modules/react-native-gesture-handler/ios/**", + "$(SRCROOT)/../node_modules/react-native-reanimated/ios/**", ); INFOPLIST_FILE = "TableViewDemo-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1508,6 +1533,8 @@ "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", ); OTHER_LDFLAGS = ( "-ObjC", diff --git a/example/package.json b/example/package.json index 801316e..2055674 100644 --- a/example/package.json +++ b/example/package.json @@ -11,8 +11,9 @@ "react": "16.8.3", "react-native": "0.59.9", "react-native-gesture-handler": "^1.3.0", + "react-native-reanimated": "^1.1.0", "react-native-tableview": "^2.5.0", - "react-navigation": "^3.11.0" + "react-navigation": "^3.11.1" }, "devDependencies": { "@babel/core": "^7.4.5", diff --git a/example/yarn.lock b/example/yarn.lock index 52ea0f7..ad76cc3 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -4924,6 +4924,11 @@ react-native-gesture-handler@^1.3.0: invariant "^2.2.2" prop-types "^15.5.10" +react-native-reanimated@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.1.0.tgz#ba6864055ec3a206cdd5209a293fe653ce276206" + integrity sha512-UGDVNfvuIkMqYUx6aytSzihuzv6sWubn0MQi8dRcw7BjgezhjJnVnJ/NSOcpL3cO+Ld7lFcRX6GKcskwkHdPkw== + react-native-safe-area-view@^0.14.1: version "0.14.5" resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.5.tgz#eeded66bbeb0807f0a7f5f449e7fb2871f7ecf76" @@ -5028,10 +5033,10 @@ react-navigation-tabs@~1.1.4: react-lifecycles-compat "^3.0.4" react-native-tab-view "^1.4.1" -react-navigation@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.0.tgz#2c82217c452d07d8b9b0929bc7e77e2bcfaf9388" - integrity sha512-wlPcDtNiIdPeYxNQ/MN4arY5Xe9EphD2QVpRuvvuPWW+BamF3AJaIy060r3Yz59DODAoWllscabat/yqnih8Tg== +react-navigation@^3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-3.11.1.tgz#ba696ad6b512088a97a20cc7e6a250c53dbddd26" + integrity sha512-n64HxLG5s5ucVFo1Gs+D9ujChhHDd98lpQ1p27wL7gq8V1PaRJMvsBEIsguhtc2rTIL/TWDynOesXQDG+Eg6FQ== dependencies: "@react-navigation/core" "~3.4.1" "@react-navigation/native" "~3.5.0" From 083632ca8bf1b55cd294cee64fcd1597c34609b5 Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Tue, 6 Aug 2019 23:16:02 -0400 Subject: [PATCH 3/4] docs: Update example and readme to use hooks --- README.md | 149 +++++++++++++++++++------------- example/src/screens/Example4.js | 86 +++++++++--------- example/src/screens/Example6.js | 84 +++++++++--------- example/src/screens/Example7.js | 115 +++++++++++++----------- example/src/screens/Example8.js | 94 ++++++++++---------- example/src/screens/Home.js | 3 +- 6 files changed, 287 insertions(+), 244 deletions(-) diff --git a/README.md b/README.md index 7f0df7d..19d06a7 100755 --- a/README.md +++ b/README.md @@ -182,44 +182,48 @@ in [Editable Complex Components](#editable-complex-components). ![demo-3](./.github/large-network-example.gif) ```jsx -state = { - loading: true, - users: [], -} - -async componentWillMount() { - const response = await fetch('https://randomuser.me/api/?results=5000') - const data = await response.json() - - this.setState({ - loading: false, - users: data.results.map(a => ({ - name: `${a.name.first} ${a.name.last}`, - id: a.registered, - })), - }) -} +() => { + const [loading, setLoading] = useState(true); + const [users, setUsers] = useState([]); + + useEffect(() => { + const getUsers = async () => { + const response = await fetch('https://randomuser.me/api/?results=5000'); + const data = await response.json(); + + setLoading(false); + setUsers( + data.results.map(a => ({ + name: `${a.name.first} ${a.name.last}`, + id: a.registered, + })) + ); + }; + + getUsers(); + }, []); -render() { return ( - {this.state.loading ? 'Fetching' : 'Fetched'} 5000 users + {loading ? 'Fetching' : 'Fetched'} 5000 users - {this.state.loading && } + {loading && }
- {this.state.users.map(a => {a.name})} + {users.map(a => ( + {a.name} + ))}
- ) -} + ); +}; ``` ### App-bundled JSON with filter and selected value checkmarked @@ -256,7 +260,7 @@ render() {
Item 1 @@ -279,59 +283,84 @@ render() { ![pull to refresh example](./.github/pull-to-refresh-example.gif) ```jsx -state = { - loading: true, - users: [], - refreshing: false, - amount: 10, +function reducer(state, action) { + switch (action.type) { + case 'getUsers': + return { ...state, loading: false, users: action.payload }; + case 'startRefresh': + return { ...state, refreshing: true }; + case 'endRefresh': + return { + ...state, + refreshing: false, + amount: state.amount + 10, + users: [...state.users, ...action.payload], + }; + default: + return state; + } } -async componentWillMount() { - const users = await this.fetchUsers() +() => { + const [{ loading, amount, refreshing, users }, dispatch] = useReducer( + reducer, + { + loading: true, + users: [], + refreshing: false, + amount: 10, + } + ); - this.setState({ - loading: false, - users, - }) -} + useEffect(() => { + const getUsers = async () => { + const data = await fetchUsers(); + dispatch({ type: 'getUsers', payload: data }); + }; -fetchUsers = async () => { - const response = await fetch('https://randomuser.me/api/?results=10') - const data = await response.json() + getUsers(); + }, []); - return data.results.map(a => ({ - name: `${a.name.first} ${a.name.last}`, - id: a.registered, - })) -} + const fetchUsers = async () => { + const response = await fetch('https://randomuser.me/api/?results=10'); + const data = await response.json(); -fetchMore = () => { - this.setState({ refreshing: true }, async () => { - const users = await this.fetchUsers() - this.setState({ users: [...users, ...this.state.users], refreshing: false, amount: this.state.amount + 10 }) - }) -} + return data.results.map(a => ({ + name: `${a.name.first} ${a.name.last}`, + id: a.login.uuid, + })); + }; + + const fetchMore = async () => { + dispatch({ type: 'startRefresh' }); + const data = await fetchUsers(); + dispatch({ type: 'endRefresh', payload: data }); + }; -render() { return ( - {this.state.loading ? 'Fetching' : 'Fetched'} {this.state.amount} users + {loading ? 'Fetching' : 'Fetched'} {amount} users - {this.state.loading && } + {loading && } -
{this.state.users.map(a => {a.name})}
+
+ {users.map(a => ( + {a.name} + ))} +
- ) + ); +}; } ``` @@ -395,14 +424,14 @@ An `image` prop can be a string pointing to the name of an asset in your "Asset Catalog". In this case an `imageWidth` prop is recommended. ```jsx -; + ``` Alternatively, you can `require` the image from your local app code. In this case an `imageWidth` is unnecessary. ```jsx -; + ``` ### Editable Complex Components @@ -492,7 +521,7 @@ For more examples, see examples/TableViewDemo. /> ); })} -
; + ``` Note that the props you pass must be primitive types: they cannot be objects. diff --git a/example/src/screens/Example4.js b/example/src/screens/Example4.js index 9faf4b1..e970e70 100644 --- a/example/src/screens/Example4.js +++ b/example/src/screens/Example4.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { View, ActivityIndicator, Text, StyleSheet } from 'react-native'; import TableView from 'react-native-tableview'; @@ -13,47 +13,47 @@ const styles = StyleSheet.create({ }, }); -class Example4 extends React.Component { - state = { - loading: true, - users: [], - }; - - async componentWillMount() { - const response = await fetch('https://randomuser.me/api/?results=5000'); - const data = await response.json(); - - this.setState({ - loading: false, - users: data.results.map(a => ({ - name: `${a.name.first} ${a.name.last}`, - id: a.registered, - })), - }); - } - - render() { - return ( - - - {this.state.loading ? 'Fetching' : 'Fetched'} 5000 users - - - {this.state.loading && } - - -
- {this.state.users.map(a => ( - {a.name} - ))} -
-
-
- ); - } -} +const Example4 = () => { + const [loading, setLoading] = useState(true); + const [users, setUsers] = useState([]); + + useEffect(() => { + const getUsers = async () => { + const response = await fetch('https://randomuser.me/api/?results=5000'); + const data = await response.json(); + + setLoading(false); + setUsers( + data.results.map(a => ({ + name: `${a.name.first} ${a.name.last}`, + id: a.registered, + })) + ); + }; + + getUsers(); + }, []); + + return ( + + + {loading ? 'Fetching' : 'Fetched'} 5000 users + + + {loading && } + + +
+ {users.map(a => ( + {a.name} + ))} +
+
+
+ ); +}; export default Example4; diff --git a/example/src/screens/Example6.js b/example/src/screens/Example6.js index ba5793b..e5de288 100644 --- a/example/src/screens/Example6.js +++ b/example/src/screens/Example6.js @@ -6,53 +6,53 @@ import TableView from 'react-native-tableview'; const { Item, Section, Consts } = TableView; -class Example6 extends React.Component { - static navigationOptions = ({ navigation }) => ({ +const Example6 = ({ navigation }) => { + return ( + + alert(JSON.stringify(event))} + onChange={event => alert(`CHANGED:${JSON.stringify(event)}`)} + > +
+ Item 1 + Item 2 + Item 3 + Item 4 +
+
+ alert(JSON.stringify(event))} + onChange={event => alert(`CHANGED:${JSON.stringify(event)}`)} + > +
+ Item 1 + Item 2 + Item 3 + Item 4 +
+
+
+ ); +}; + +Example6.navigationOptions = ({ navigation }) => { + const editing = navigation.getParam('editing'); + + return { headerRight: (