Skip to content

With router-flux: Tab re-renders one more time #47

@dswbx

Description

@dswbx

Using:
react-native-router-flux@3.36.0
react-native-tabs@1.0.9
react-native@0.35.0
react@15.3.2

Demo

Description:

  1. start app, renders tab "Feed" initially
  2. switch to "Tab How to change View #2" and then back to "Feed" - this re-renders tab "Feed"
  3. switching to second and back to initial tab does not re-render tab "Feed" again

I expect tabs to not re-render, but I think this is caused by tab 2 being rendered after clicked (and forces tab 1 to re-render as well). Is there an option to automatically render all tabs at start? Or is this behavior caused by something else? I've attached all that might be helpful, sorry if this post is very long.

Scenes:

//...
class AppNavigator extends React.Component
{
    render()
    {
        return <RouterWithRedux>
            <Scene key="root" style={{backgroundColor: 'yellow'}}>
                <Scene open={false} component={Drawer} key="drawer" sceneStyle={[AppStyle.sceneTab, {borderWidth: 1, borderColor: 'red'}]}>
                    <Scene key="main" tabs initial={true} tabBarStyle={{backgroundColor: 'rgba(0,0,0,.4)', borderWidth: 1, borderColor: 'blue'}}>
                        <Scene key="main_back" onPress={() => Actions.pop()} title="Back" icon={TabIcon} />

                        <Scene key="Page1" title="Feed" icon={TabIcon} initial={true} sceneStyle={{borderWidth: 1, borderColor: 'green'}}>
                            <Scene key="Feed" component={Scenes.Page1} hideNavBar={true} initial={true} sceneStyle={{borderWidth: 1, borderColor: 'yellow', backgroundColor: 'yellow'}} />
                            <Scene key="detail" component={Scenes.Page3} hideNavBar={true} title="PostDetail" />
                        </Scene>

                        <Scene key="Page2" component={Scenes.Page2} hideNavBar={true} title="Tab #2" icon={TabIcon} />
                        <Scene key="open_drawer" title="Drawer" icon={TabIcon} onPress={() => Actions.refresh({key: 'drawer', open: value => !value })} />
                    </Scene>

                    <Scene key="auth" type={ActionConst.REPLACE}>
                        <Scene key="Login" component={Scenes.Login} title="Login" initial={true} />
                        <Scene key="Register" component={Scenes.Register} title="Register" />
                    </Scene>
                </Scene>
            </Scene>
        </RouterWithRedux>
    }
}

function mapDispatchToProps(dispatch)
{
    return bindActionCreators(ActionCreators, dispatch);
}

export default connect((state) => {
    return {}
}, mapDispatchToProps)(AppNavigator);

Page1.js (Feed tab):

//...
class Page1 extends Component
{
    _addRecipe()
    {
        this.props.addRecipe();
    }

    componentDidMount()
    {
        this.props.fetchPosts();
    }

    render()
    {
        console.log('page1props', this.props);

        return <AnimatableScrollView
            animation="fadeIn"
            contentContainerStyle={[ ScrollViewStyle.contentContainerStyle ]}
            style={[ AppStyle.sceneTabInner, ScrollViewStyle.style ]}
        >
            <Animatable.Text animation="zoomIn" style={{color: 'white'}} onPress={Actions.Page2}>
                Page1
            </Animatable.Text>
            <Text onPress={() => this._addRecipe()}>Add recipe</Text>
            <Text>Recipe count: {this.props.recipeCount}</Text>
            <Text style={{marginTop:40}} onPress={() => Actions.auth()}>Goto login</Text>
            {this.props.posts.length > 0 && this.props.posts.map((value, key) => {
                postAnimationDelay += postAnimationIteration;

                return <Animatable.View animation="fadeInUp" delay={postAnimationDelay} duration={300} key={value.id} style={{marginTop: 20}}>
                    <TouchableOpacity onPress={() => Actions.detail({
                        post: value
                    })}>
                        <Text>{value.title}</Text>
                    </TouchableOpacity>
                </Animatable.View>
            })}
            <Text onPress={() => Actions.detail()} style={{marginTop:40}}>asdf</Text>
        </AnimatableScrollView>
    }
}


export default connect((state) => { // state == global state
    return {
        routes: state.routes,
        searchedRecipes: state.searchedRecipes,
        recipeCount: state.recipeCount,
        posts: state.posts
    }
}, (dispatch) => bindActionCreators(ActionCreators, dispatch))(Page1);

Page2.js (Tab #2):

//...
class Page2 extends Component
{
    _removeRecipe()  { this.props.removeRecipe();  }

    render()
    {
        return <View style={{flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'red'}}>
            <Text style={{color: 'white'}} onPress={Actions.pop}>
                Page2
            </Text>
            <Text onPress={() => this._removeRecipe()}>Remove recipe</Text>
            <Text>Recipe count: {this.props.recipeCount}</Text>
            <Text style={{marginTop:40}} onPress={() => Actions.auth()}>Goto login</Text>
        </View>
    }
}

export default connect((state) => { // state == global state
    return {
        routes: state.routes,
        searchedRecipes: state.searchedRecipes,
        recipeCount: state.recipeCount
    }
}, (dispatch) => bindActionCreators(ActionCreators, dispatch))(Page2);

Console ouput of Demo GIF:

Running application App ({
    initialProps =     {
    };
    rootTag = 1;
})
Running application "App" with appParams: {"rootTag":1,"initialProps":{}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF
fetching url https://...
 action @ 13:06:08.324 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action @ 13:06:08.336 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action @ 13:06:08.749 REACT_NATIVE_ROUTER_FLUX_REFRESH 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action Object {key: "0_drawer", open: false, type: "REACT_NATIVE_ROUTER_FLUX_REFRESH"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action @ 13:06:08.753 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
response Object {limit: 10, offset: 0, data: Array[10], single_result: false}
 action @ 13:06:09.151 SET_POSTS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[0]}
 action Object {type: "SET_POSTS", posts: Array[10]}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:38.433 REACT_NATIVE_ROUTER_FLUX_JUMP 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {key: "Page2", type: "REACT_NATIVE_ROUTER_FLUX_JUMP"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:38.438 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:38.469 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:40.121 REACT_NATIVE_ROUTER_FLUX_JUMP 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {key: "Page1", type: "REACT_NATIVE_ROUTER_FLUX_JUMP"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:40.125 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:40.137 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
fetching url https://...
response Object {limit: 10, offset: 0, data: Array[10], single_result: false}
 action @ 13:06:41.602 SET_POSTS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {type: "SET_POSTS", posts: Array[10]}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.044 REACT_NATIVE_ROUTER_FLUX_JUMP 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {key: "Page2", type: "REACT_NATIVE_ROUTER_FLUX_JUMP"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.048 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.062 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.919 REACT_NATIVE_ROUTER_FLUX_JUMP 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {key: "Page1", type: "REACT_NATIVE_ROUTER_FLUX_JUMP"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.926 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action @ 13:06:50.947 REACT_NATIVE_ROUTER_FLUX_FOCUS 
 prev state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}
 action Object {scene: Object, type: "REACT_NATIVE_ROUTER_FLUX_FOCUS"}
 next state Object {searchedRecipes: Object, recipeCount: 17, routes: Object, posts: Array[27261]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions