From 679fb2db2170f3e764a34a06c7bd4b172dacf1aa Mon Sep 17 00:00:00 2001 From: burczu Date: Mon, 31 Jul 2023 10:03:19 +0200 Subject: [PATCH 1/6] migration from class to functional component --- src/components/GrowlNotification/index.js | 128 +++++++++++----------- 1 file changed, 62 insertions(+), 66 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index b995d0ec7039..b0ba5d466d9d 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -1,6 +1,6 @@ -import React, {Component} from 'react'; -import {View, Animated} from 'react-native'; +import React, {useCallback, useEffect, useState} from 'react'; import {Directions, FlingGestureHandler, State} from 'react-native-gesture-handler'; +import {View, Animated} from 'react-native'; import colors from '../../styles/colors'; import Text from '../Text'; import Icon from '../Icon'; @@ -29,24 +29,12 @@ const types = { const INACTIVE_POSITION_Y = -255; const PressableWithoutFeedback = Pressables.PressableWithoutFeedback; +const translateY = new Animated.Value(INACTIVE_POSITION_Y); -class GrowlNotification extends Component { - constructor(props) { - super(props); - - this.state = { - bodyText: '', - type: 'success', - translateY: new Animated.Value(INACTIVE_POSITION_Y), - }; - - this.show = this.show.bind(this); - this.fling = this.fling.bind(this); - } - - componentDidMount() { - Growl.setIsReady(); - } +function GrowlNotification() { + const [bodyText, setBodyText] = useState(''); + const [type, setType] = useState('success'); + const [duration, setDuration] = useState(); /** * Show the growl notification @@ -55,65 +43,73 @@ class GrowlNotification extends Component { * @param {String} type * @param {Number} duration */ - show(bodyText, type, duration) { - this.setState( - { - bodyText, - type, - }, - () => { - this.fling(0); - setTimeout(() => { - this.fling(INACTIVE_POSITION_Y); - }, duration); - }, - ); - } + // eslint-disable-next-line no-unused-vars + const show = useCallback((text, growlType, growlDuration) => { + setBodyText(text); + setType(growlType); + setDuration(growlDuration); + }, []); /** * Animate growl notification * * @param {Number} val */ - fling(val = INACTIVE_POSITION_Y) { - Animated.spring(this.state.translateY, { + const fling = useCallback((val = INACTIVE_POSITION_Y) => { + Animated.spring(translateY, { toValue: val, duration: 80, useNativeDriver: true, }).start(); - } + }, []); - render() { - return ( - { - if (nativeEvent.state !== State.ACTIVE) { - return; - } + useEffect(() => { + Growl.setIsReady(); + }, []); + + useEffect(() => { + if (!duration) { + return; + } + + fling(0); + setTimeout(() => { + fling(INACTIVE_POSITION_Y); + setDuration(undefined); + }, duration); + }, [duration, fling]); - this.fling(INACTIVE_POSITION_Y); - }} - > - - - this.fling(INACTIVE_POSITION_Y)} - > - - - {this.state.bodyText} - - - - - - ); - } + return ( + { + if (nativeEvent.state !== State.ACTIVE) { + return; + } + + fling(INACTIVE_POSITION_Y); + }} + > + + + fling(INACTIVE_POSITION_Y)} + > + + + {bodyText} + + + + + + ); } +GrowlNotification.displayName = 'GrowlNotification'; + export default GrowlNotification; From a64d2b5a036cc4bc231cf22a4147f1a74766047a Mon Sep 17 00:00:00 2001 From: burczu Date: Tue, 1 Aug 2023 11:20:19 +0200 Subject: [PATCH 2/6] exposing the show method via ref --- src/components/GrowlNotification/index.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index b0ba5d466d9d..35981524bbd8 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -1,4 +1,4 @@ -import React, {useCallback, useEffect, useState} from 'react'; +import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useState} from 'react'; import {Directions, FlingGestureHandler, State} from 'react-native-gesture-handler'; import {View, Animated} from 'react-native'; import colors from '../../styles/colors'; @@ -31,7 +31,7 @@ const INACTIVE_POSITION_Y = -255; const PressableWithoutFeedback = Pressables.PressableWithoutFeedback; const translateY = new Animated.Value(INACTIVE_POSITION_Y); -function GrowlNotification() { +function GrowlNotification(_, ref) { const [bodyText, setBodyText] = useState(''); const [type, setType] = useState('success'); const [duration, setDuration] = useState(); @@ -43,7 +43,6 @@ function GrowlNotification() { * @param {String} type * @param {Number} duration */ - // eslint-disable-next-line no-unused-vars const show = useCallback((text, growlType, growlDuration) => { setBodyText(text); setType(growlType); @@ -63,6 +62,14 @@ function GrowlNotification() { }).start(); }, []); + useImperativeHandle( + ref, + () => ({ + show, + }), + [show], + ); + useEffect(() => { Growl.setIsReady(); }, []); @@ -112,4 +119,4 @@ function GrowlNotification() { GrowlNotification.displayName = 'GrowlNotification'; -export default GrowlNotification; +export default forwardRef(GrowlNotification); From d5df95c097cbbdc9aa0b28ef58b59ff95937bfe2 Mon Sep 17 00:00:00 2001 From: burczu Date: Tue, 1 Aug 2023 11:22:10 +0200 Subject: [PATCH 3/6] unnecessary variable passing removed --- src/components/GrowlNotification/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index 35981524bbd8..9fedf3c4e11d 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -81,7 +81,7 @@ function GrowlNotification(_, ref) { fling(0); setTimeout(() => { - fling(INACTIVE_POSITION_Y); + fling(); setDuration(undefined); }, duration); }, [duration, fling]); @@ -94,14 +94,14 @@ function GrowlNotification(_, ref) { return; } - fling(INACTIVE_POSITION_Y); + fling(); }} > fling(INACTIVE_POSITION_Y)} + onPress={() => fling()} > Date: Tue, 1 Aug 2023 13:59:28 +0200 Subject: [PATCH 4/6] storing translateY animated value in ref --- src/components/GrowlNotification/index.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index 9fedf3c4e11d..60bd1bf00587 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -1,4 +1,4 @@ -import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useState} from 'react'; +import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react'; import {Directions, FlingGestureHandler, State} from 'react-native-gesture-handler'; import {View, Animated} from 'react-native'; import colors from '../../styles/colors'; @@ -29,9 +29,9 @@ const types = { const INACTIVE_POSITION_Y = -255; const PressableWithoutFeedback = Pressables.PressableWithoutFeedback; -const translateY = new Animated.Value(INACTIVE_POSITION_Y); function GrowlNotification(_, ref) { + const translateY = useRef(new Animated.Value(INACTIVE_POSITION_Y)).current; const [bodyText, setBodyText] = useState(''); const [type, setType] = useState('success'); const [duration, setDuration] = useState(); @@ -54,13 +54,16 @@ function GrowlNotification(_, ref) { * * @param {Number} val */ - const fling = useCallback((val = INACTIVE_POSITION_Y) => { - Animated.spring(translateY, { - toValue: val, - duration: 80, - useNativeDriver: true, - }).start(); - }, []); + const fling = useCallback( + (val = INACTIVE_POSITION_Y) => { + Animated.spring(translateY, { + toValue: val, + duration: 80, + useNativeDriver: true, + }).start(); + }, + [translateY], + ); useImperativeHandle( ref, From 37facb59be608c2a1a9ee5ff5cce1a7277a94c78 Mon Sep 17 00:00:00 2001 From: burczu Date: Tue, 1 Aug 2023 13:59:53 +0200 Subject: [PATCH 5/6] simplified onPress handler assignment --- src/components/GrowlNotification/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index 60bd1bf00587..9b32f8651939 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -104,7 +104,7 @@ function GrowlNotification(_, ref) { fling()} + onPress={fling} > Date: Tue, 1 Aug 2023 14:47:06 +0200 Subject: [PATCH 6/6] fling on press reverted to be called explicitly --- src/components/GrowlNotification/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js index 9b32f8651939..60bd1bf00587 100644 --- a/src/components/GrowlNotification/index.js +++ b/src/components/GrowlNotification/index.js @@ -104,7 +104,7 @@ function GrowlNotification(_, ref) { fling()} >