React-native-router-flux: Rerendering a tab when clicking to it?

Created on 4 Sep 2016  路  15Comments  路  Source: aksonov/react-native-router-flux

Version

  • react-native-router-flux v3.35.0
  • react-native v0.32.0

How do I rerender a tab to display updated data within my drawer when I click to it?

I have tried:

onPress={() => { drawer.close(); Actions.historyPage(); Actions.refresh() }}

but then it doesn't do anything.

import React, { Component, PropTypes } from 'react';
import { Platform, TouchableOpacity, StyleSheet, Text, View } from 'react-native';
import { Actions, DefaultRenderer } from 'react-native-router-flux';
import Drawer from 'react-native-drawer';
import db from './RealmMigration';

export default class extends Component {
    render(){
        const state = this.props.navigationState;
        const children = state.children;
        return (
            <Drawer
              open={state.open}
              onOpen={()=>Actions.refresh({key:state.key, open: true})}
              onClose={()=>Actions.refresh({key:state.key, open: false})}
              type="overlay"
              content={<SideMenu />}
              tapToClose={true}
              openDrawerOffset={0.35}
              panCloseMask={0.35}
              styles={drawerStyles}
              negotiatePan={true}
              tweenHandler={(ratio) => ({
               main: { opacity:Math.max(0.54,1-ratio) }
            })}>
                <DefaultRenderer navigationState={children[0]} onNavigate={this.props.onNavigate} />
            </Drawer>
        );
    }
}

const SideMenu = (props, context) => {
  const drawer = context.drawer;
  return (
    <View style={styles.container}>
      <View style={styles.header}>

      </View>
      <PageLink text={"Solve Lessons"} onPress={() => { drawer.close(); Actions.problemPage(); }} />
      <PageLink text={"History"} onPress={() => { drawer.close(); Actions.historyPage(); }} />
      <PageLink text={"Bookmarks"} onPress={() => { drawer.close(); Actions.bookmarksPage({bookmarks: db.objects('Problem').filtered('bookmark == true').sorted('bookmarkedOn')}); }} />
      <PageLink text={"Settings"} onPress={() => { drawer.close(); Actions.settingsPage(); }} />
      <PageLink text={"About"} onPress={() => { drawer.close(); Actions.aboutPage(); }} />
    </View>
  );
};

SideMenu.contextTypes = {
  drawer: React.PropTypes.object,
};

SideMenu.PropTypes = {
  name: PropTypes.string,
  sceneStyle: View.propTypes.style,
  title: PropTypes.string,
};

class PageLink extends Component {
  render() {
    return (
      <TouchableOpacity onPress={this.props.onPress} style={styles.pageLink}>
        <Text style={styles.pageLinkText}>{this.props.text}</Text>
      </TouchableOpacity>
    );
  }
}

Most helpful comment

@hejiaji any luck with that issue? I'm facing the same problem!

All 15 comments

Maybe use type={ActionConst.RESET} or use polling

Thanks!

@linonetwo I have also been trying to get this to work for a while now and that solution does not work for be. I am on v3.34, but that shouldn't make a difference?

Also, I am assuming you mean type={ActionConst.RESET} unless
ActionConst changed to ActionConstants in 3.35?

sorry @tuneZola I typo it, of course It 's type={ActionConst.RESET}. I updated my comment, thanks.

@linonetwo, i'm tryed to do the same, but after clicking on the tab, tab bar begins to show only the tab i clicked (like there is only one scene):

<Scene key="main" tabs tabBarStyle={{backgroundColor: 'white'}} tabBarSelectedItemStyle={styles.tabBarSelectedItemStyle}>
    <Scene key="Tab#1" title="Tab#1" initial icon={TabIcon}>
        <Scene key="Tab#1_1" component={FirstView} title="Tab#1_1" initial icon={TabIcon}/>
        <Scene key="Tab#1_2" component={SecondView} title="Tab#1_2" icon={TabIcon} renderLeftButton/>
    </Scene>
    <Scene key="Tab#2" component={ThirdView} title="Tab#2" icon={TabIcon} initial type={ActionConst.RESET}/>
    <Scene key="Tab#3" component={FourthView} title="Tab#3" icon={TabIcon} />
</Scene>

@MuffinWithJam I have tried tons of ways to get tab reload. Here are some worked workarounds for it:

  1. Actions.pop(); Actions.Tab#1(); // pop to main then reEnter the scene.
  2. move all the setUp work you want this tab to do to redux, in the reducer , watch ActionConst.JUMP, then do some setUp work you want. ( I finally use this one )
  3. use an intermediate page, ActionConst.PUSH to that page then do some setUp work, then pop and jump.

@linonetwo the method 1, Actions.pop(), Actions.Tab#1() seems not work in my case, the tab didn't get reloaded when reEnter the scene

@aksonov is there a way to rerender a component when click a tab? we got a requirement that refresh the component when switch tabs...

@linonetwo I encountered the same situation with @MuffinWithJam, unfortunately it's not only setUp work i need to do, i actually want it reRender to load data from server, it's like i need to unmount the component when switch up to another tab... is there any way we can try?

@dragfire Thanks for your reply, but this method doesn't fit me, i need the component to unmount and remount again when click the tab, not just render it. cause i need to decide when to fetch data. obviously i can't put the fetch logic in render(), ideally i want to put the fetch logic in ComponentDidMount, that's why i need unmount the component when switch out.

@hejiaji any luck with that issue? I'm facing the same problem!

@willyyang hey, yes, i found a workaround for this specific requirement by link it to reducer. by add listener to hook componentWillReceiveProps, to decide if we load data (refresh) from the flag we set in reducer. (flag for example: shouldRenderHome). we subscribe the ActionConst.JUMP action in reducer and set shouldRender flags to true, then in the componentWillReceiveProps hook, we load the data and set it to false.

Hope this would help you

@willyyang, what method are you calling to rerender your component if your flag evaluates to true in componentWillReceiveProps? Actions.refresh() doesn't seem to do anything, neither does the react-native API this.forceUpdate()

@JohnAntonusMaximus you just need simplely add logic in componentWillReceiveProps hook function like this:

componentWillReceiveProps(nextProps) {
if (nextProps.shouldRender) {
this.props.resetShouldRender();
// fetch data here
}
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tonypeng picture tonypeng  路  3Comments

wootwoot1234 picture wootwoot1234  路  3Comments

vinayr picture vinayr  路  3Comments

sreejithr picture sreejithr  路  3Comments

xnog picture xnog  路  3Comments