IjzerenHein / react-navigation-shared-element

React Navigation bindings for react-native-shared-element 💫
https://github.com/IjzerenHein/react-native-shared-element
MIT License
1.27k stars 124 forks source link

shared element is animating without anything different in dom between screen 1 and screen 2 #192

Open jsindos opened 2 years ago

jsindos commented 2 years ago

Hi, for some reason there is an animation of my shared element even though the DOM of the two screens housing the component are completely identical. Screen 2 is navigated to from screen 1 when the TextInput is focussed.

https://user-images.githubusercontent.com/8110172/132151190-edf63f49-776e-4888-8dbd-8b48ffcb38fd.mov

I am on the navigation-v5 branch.

navigator

import React from 'react'
import { createSharedElementStackNavigator } from 'react-navigation-shared-element'
import { enableScreens } from 'react-native-screens'
enableScreens()

import Explore from './Explore'
import Search from './Search'

const Stack = createSharedElementStackNavigator()

export default () => {
  return (
    <Stack.Navigator headerMode='none'>
      <Stack.Screen name='Explore' component={Explore} />
      <Stack.Screen
        name='Search' component={Search} options={() => ({
          gestureEnabled: false
        })}
      />
    </Stack.Navigator>
  )
}

screen 1

import React from 'react'
import { View } from 'react-native'
import { SharedElement } from 'react-navigation-shared-element'

import SearchBar from './SearchBar'

export default () => {
  return (
    <View>
      <SharedElement id='searchBar'>
        <SearchBar />
      </SharedElement>
    </View>
  )
}

screen 2

import React from 'react'
import { View } from 'react-native'
import { SharedElement } from 'react-navigation-shared-element'

import SearchBar from './SearchBar'

const Search = () => {
  return (
    <View>
      <SharedElement id='searchBar'>
        <SearchBar />
      </SharedElement>
    </View>
  )
}

Search.sharedElements = (route, otherRoute, showing) => {
  return ['searchBar']
}

export default Search

shared element

import React from 'react'
import styled from 'styled-components/native'
import { useNavigation } from '@react-navigation/native'
import { View, Animated } from 'react-native'

import Search from '../assets/Search'

export default () => {
  const navigation = useNavigation()

  return (
    <View style={{ marginTop: 10, marginBottom: 10, alignItems: 'center' }}>
      <$SearchBar style={{ marginRight: 5 }}>
        <Search style={{ marginLeft: 8 }} />
        <$SearchText
          placeholder='What are you looking for?'
          onFocus={() => navigation.navigate('Search')}
        />
      </$SearchBar>
    </View>
  )
}

const $SearchBar = styled(Animated.View)`
  alignItems: center;
  paddingVertical: 10px;
  paddingHorizontal: 10px;
  display: flex;
  justifyContent: center;
  flexDirection: row;
  backgroundColor: #FFF;
`

const $SearchText = styled.TextInput`
  fontSize: 14px;
  flex: 1;
  color: #222;
  fontFamily: "OpenSans-SemiBold";
  textAlign: left;
  marginLeft: 12px;
  outline-style: none;
`
jsindos commented 2 years ago

Hi, I switched to the main branch, "react-navigation-shared-element": "^3.1.3". There is a different issue now, the component "blinks" when transitioning.

https://user-images.githubusercontent.com/8110172/132606987-0cc5025e-729c-42ab-a2bc-f44aec4c4945.mov

I can confirm the navigation system is doing something, because when I remove the static config in screen 2 the blinking goes away.

navigator

import React from 'react'
import { createSharedElementStackNavigator } from 'react-navigation-shared-element'
import { enableScreens } from 'react-native-screens'

import Explore from './Explore'
import Search from './Search'
enableScreens()

const Stack = createSharedElementStackNavigator()

export default () => {
  return (
    <Stack.Navigator headerMode='none'>
      <Stack.Screen name='Explore' component={Explore} initialParams={{ title: 'Explore' }} />
      <Stack.Screen
        name='Search' component={Search} options={() => ({
          gestureEnabled: false
        })}
        initialParams={{ title: 'Search' }}
      />
    </Stack.Navigator>
  )
}

screen 1

import React from 'react'
import { View, Text } from 'react-native'
import { SharedElement } from 'react-navigation-shared-element'

import SearchBar from './SearchBar'

export default ({ route: { params } }) => {
  return (
    <View>
      <Text>
        Hello
      </Text>
      <SharedElement id='searchBar'>
        <SearchBar {...params} />
      </SharedElement>
    </View>
  )
}

screen 2

import React from 'react'
import { View, Text } from 'react-native'
import { SharedElement } from 'react-navigation-shared-element'

import SearchBar from './SearchBar'

const Search = ({ route: { params } }) => {
  return (
    <View>
      <SharedElement id='searchBar'>
        <SearchBar {...params} />
      </SharedElement>
      <Text>
        Hello
      </Text>
    </View>
  )
}

Search.sharedElements = (route, otherRoute, showing) => {
  return ['searchBar']
}

export default Search

shared element

import React from 'react'
import { useNavigation } from '@react-navigation/native'
import { View, Text } from 'react-native'

export default ({ title }) => {
  const navigation = useNavigation()

  return (
    <View style={[{ paddingTop: 10, paddingBottom: 10, alignItems: 'center' }]}>
      <Text onPress={() => navigation.navigate('Search')} style={{ fontSize: 32 }}>
        {title}
      </Text>
    </View>
  )
}
jsindos commented 2 years ago

Hi, I just tested in the ios simulator and the blinking goes away. Realised the transitions don't work when running expo web which I am OK with :)

IjzerenHein commented 2 years ago

Yeah web is not supported yet (unfinished implementation) https://github.com/IjzerenHein/react-native-shared-element#under-development