I am using react-native-tab-view for creating swipe tabs, but when I swipe from one tab to another I get my us effect of each component called every time when I swipe it.
My problem is similar as this issue on Github: https://github.com/satya164/react-native-tab-view/issues/750
Current behaviour
When I use 'switch render' scene inside of the hooks function - I get two renders (when we just start app):
const _renderScene = ({ route }) => {
switch (route.key) {
case 'login':
return <FirstRoute />;
case 'sign_up':
return <SecondRoute />;
default:
return null;
}
};
index.js:17 FirstRoute
index.js:28 SecondRoute
index.js:17 FirstRoute
index.js:28 SecondRoute
When switch between tabs - also received two render - every time!
index.js:17 FirstRoute
index.js:28 SecondRoute
Expected behaviour
When use the same code but with this method:
const _renderScene = SceneMap({
login: FirstRoute,
sign_up: SecondRoute,
});
Code sample:
import React, { useState } from 'react';
import {
Text,
View,
Keyboard,
} from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import { TabView, TabBar, SceneMap } from 'react-native-tab-view';
import { DEVICE_WIDTH } from 'config/constants';
import styles from './styles';
const FirstRoute = () => {
console.log('FirstRoute');
return (
<View>
<Text>
Lorem ipsum dolor sit amet
</Text>
</View>
);
};
const SecondRoute = () => {
console.log('SecondRoute');
return (
<View>
<Text>
Lorem ipsum dolor sit amet
</Text>
</View>
);
};
const INITIAL_STATE = {
index: 0,
routes: [
{
key: 'login',
title: 'Login',
icon: '',
accessibilityLabel: 'Login',
testID: 'loginTab',
},
{
key: 'sign_up',
title: 'Register',
icon: '',
accessibilityLabel: 'SignIn',
testID: 'signInTab',
},
],
};
const LoginScreen = () => {
const [state, setState] = useState(INITIAL_STATE);
const _renderScene = SceneMap({
login: FirstRoute,
sign_up: SecondRoute,
});
// const _renderScene = ({ route }) => {
// switch (route.key) {
// case 'login':
// return <FirstRoute />;
// case 'sign_up':
// return <SecondRoute stings={[]} />;
// default:
// return null;
// }
// };
const _handleIndexChange = (index) => {
Keyboard.dismiss();
setState({ ...INITIAL_STATE, index });
};
const _renderTabBar = props => (
<TabBar
{...props}
activeColor={EStyleSheet.value('$primaryColor')}
inactiveColor="black"
style={styles.tabBar}
indicatorStyle={styles.indicatorStyle}
/>
);
return (
<View style={styles.container}>
<TabView
// lazy
navigationState={state}
renderScene={_renderScene}
renderTabBar={_renderTabBar}
onIndexChange={_handleIndexChange}
// swipeEnabled={false}
initialLayout={{
height: 0,
width: DEVICE_WIDTH,
}}
/>
</View>
);
};
export default LoginScreen;
I tried below a few solutions, but all in vain. Pease help.
Used useCallBack:
const _renderScene = useCallback(SceneMap({ login: FirstRoute, sign_up: SecondRoute }));
Also used useMemo but got the error bellow:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
const firstRoute = useMemo(() => (), []);
or
const LoginUser = React.memo(() => ());
Please help.
Expected behaviour
When use the same code but with this method
const _renderScene = SceneMap({ login: FirstRoute, sign_up: SecondRoute, });
All as expected (when we just start app)
index.js:17 FirstRoute index.js:28 SecondRoute