diff --git a/example/src/App.js b/example/src/App.js
index 8dcf528..5f93e01 100644
--- a/example/src/App.js
+++ b/example/src/App.js
@@ -1,5 +1,5 @@
-import React from 'react'
-import { StyleSheet, Text, View } from 'react-native'
+import React, { useState } from 'react'
+import { StyleSheet, Text, View, Button } from 'react-native'
import Steve from 'react-native-steve'
const topics = [
@@ -62,6 +62,7 @@ const topics = [
]
export default function App() {
+ const [data, setData] = useState(topics)
const {
topicContainer,
topicText,
@@ -84,19 +85,27 @@ export default function App() {
)
}
+ const handleUpdateDataButtonClick = () => {
+ setData(topics.filter((_, index) => index < Math.random() * 10).reverse())
+ }
+
return (
{'TOPICS TO EXPLORE'}
item.text}/>
+
+
)
}
diff --git a/package.json b/package.json
index cf88afd..f7dea93 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,9 @@
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
+ "dependencies": {
+ "react-fast-compare": "^3.2.0"
+ },
"devDependencies": {
"@commitlint/config-conventional": "^11.0.0",
"@react-native-community/eslint-config": "^2.0.0",
diff --git a/src/Steve.js b/src/Steve.js
index ddbaba1..4cc7c2c 100644
--- a/src/Steve.js
+++ b/src/Steve.js
@@ -1,16 +1,20 @@
-import React, { useRef, useState } from 'react'
+import React, { useRef, useEffect } from 'react'
import Animated, {
useAnimatedGestureHandler,
useSharedValue,
withSpring,
cancelAnimation,
useAnimatedStyle,
- withDecay
+ withDecay,
+ withTiming
} from 'react-native-reanimated'
-import { Dimensions } from 'react-native'
+import { Dimensions, LayoutAnimation } from 'react-native'
import { PanGestureHandler } from 'react-native-gesture-handler'
+import isEqual from 'react-fast-compare'
+import { useObjectState } from 'hooks'
const { width: screenWidth } = Dimensions.get('window')
+const TIMING_ANIMATION_DURATION = 300
const getContainerHorizontalSpacing = style => {
const {
@@ -28,8 +32,11 @@ const getContainerHorizontalSpacing = style => {
}
export const Steve = ({ data, renderItem, keyExtractor, containerStyle, isRTL, itemStyle }) => {
+ const [{ dataCache, itemLayouts }, setState] = useObjectState({
+ dataCache: data,
+ itemLayouts: {}
+ })
const itemLayoutsCache = useRef({})
- const [itemLayouts, setItemLayouts] = useState({})
const containerHorizontalSpacing = getContainerHorizontalSpacing(containerStyle)
const translateX = useSharedValue(0)
const rtlStyle = isRTL ? { flexDirection: 'row-reverse' } : {}
@@ -98,10 +105,25 @@ export const Steve = ({ data, renderItem, keyExtractor, containerStyle, isRTL, i
)
}
}
- })
+ }, [itemLayouts])
+
+ useEffect(() => {
+ (async () => {
+ if (!isEqual(dataCache, data)) {
+ translateX.value = withTiming(0)
+ LayoutAnimation.easeInEaseOut()
+ await new Promise(resolve => setTimeout(resolve, TIMING_ANIMATION_DURATION))
+ setState({
+ dataCache: data,
+ itemLayouts: {}
+ })
+ itemLayoutsCache.current = {}
+ }
+ })()
+ }, [data, dataCache])
const Items = () => {
- return data.map((item, index) => {
+ return dataCache.map((item, index) => {
const itemKey = keyExtractor(item, index)
return (
- {
diff --git a/src/hooks/index.js b/src/hooks/index.js
new file mode 100644
index 0000000..4ccd34b
--- /dev/null
+++ b/src/hooks/index.js
@@ -0,0 +1 @@
+export * from 'hooks/useObjectState'
\ No newline at end of file
diff --git a/src/hooks/package.json b/src/hooks/package.json
new file mode 100644
index 0000000..d2902f9
--- /dev/null
+++ b/src/hooks/package.json
@@ -0,0 +1,3 @@
+{
+ "name": "hooks"
+}
\ No newline at end of file
diff --git a/src/hooks/useObjectState.js b/src/hooks/useObjectState.js
new file mode 100644
index 0000000..f7b89b2
--- /dev/null
+++ b/src/hooks/useObjectState.js
@@ -0,0 +1,6 @@
+import { useState } from 'react'
+
+export const useObjectState = initialState => {
+ const [state, setState] = useState(initialState)
+ return [state, state => setState(prevState => ({ ...prevState, ...state }))]
+}
\ No newline at end of file
diff --git a/src/package.json b/src/package.json
new file mode 100644
index 0000000..a86697a
--- /dev/null
+++ b/src/package.json
@@ -0,0 +1,3 @@
+{
+ "name": "src"
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index e501765..fdd4473 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7818,6 +7818,11 @@ react-devtools-core@^4.6.0:
shell-quote "^1.6.1"
ws "^7"
+react-fast-compare@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
+ integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
+
react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"