简体   繁体   中英

React Native - Navigator change routes

I'm using a Navigator object which renders news posts.

The idea is that you're viewing a single news post, and you can swipe left and right for the next and previous post. For example, when you swipe right it swipes to the next post. What I want is when I swipe to the next post, I want to load the next post of that post again, so you can keep swiping.

I give these props:

getInitialState: function() {
  return {
    post: {},
    routes: [this.props.prevPost, this.props.post, this.props.nextPost],
    startRoute: this.props.post,
  };
}

My Navigator function looks like this:

render: function() {
  var self = this;
  return (
    <Navigator
      debugOverlay={false}
      ref={(navigator) => {
        this._navigator = navigator;
      }}
      onDidFocus={this.itemChangedFocus}
      initialRoute={this.state.startRoute}
      initialRouteStack={this.state.routes}
      routeStack={this.state.routes}
      renderScene={this.renderNewsItem}
      configureScene={() => ({
        ...Navigator.SceneConfigs.HorizontalSwipeJump,
      })} />
  );
}

So my idea was onDidFocus , I look at my current post, I then grab the previous and next post and somehow (here's where I'm stuck) trigger a rerender of the navigator component?

This is how my itemChangedFocus function looks like:

// Route gives the current news item which has the focus
itemChangedFocus: function(route) {
  // PostStore returns a posts array
  // posts[0] = previousPost, posts[1] = currentPost, posts[2] = nextPost
  let posts = PostStore.getPrevAndNextPost(route);
  // This is probably wrong, but it did replace the nextPost in the route object
  this.props.navigator.route.nextPost = posts[2];
  // Now I need to trigger a rerender? I tried it with setState but that didn't work
}

So the question is, how do I approach this correctly? What am I doing wrong and how can I make sure I can keep swiping in the list?

How about running "forceUpdate" on navigator after setting all props? That should do the trick (it should call render method on all the scenes in theory).

BTW. I think this is not the best way of using navigator for what you want to do - because it does not use the built-in state of Navigator properly.

If you always want to keep 3 posts rendered (current, prev, next) I think a better solution could be to use replaceAtIndex(route, index) method or even immediatelyResetRouteStack(routeStack) , it should properly modify state for the Navigator and let it render accordingly. One difficulty might be to avoid animation in this case (I am not sure if immediatelyResetRouteStack will cause the animation). Maybe you will also need to jumpTo(route) as well after the reset so that no animation is triggered.

If you have limited maximum number of posts at a time on the other hand and you will be able to keep them all rendered, then you do not need to do any magic, you simply need to do push(route) for any new posts and then jumpBack() immediately - it should probably work.

After the swipe forward completes, the didFocus callback will fire. Then you can use navigator.replaceAtIndex(nextRoute, this.state.routes.length) to inject the route for the next scene.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM