React-native-router-flux: 弹出后强制重新渲染场景

创建于 2016-04-05  ·  58评论  ·  资料来源: aksonov/react-native-router-flux

你好,

单击上一个状态的“返回”按钮后,是否可以强制重新渲染场景?

谢谢

最有用的评论

我最终会通过在延迟后使用道具调用空刷新来解决它吗
Actions.popTo('pageOne');
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

所有58条评论

感谢您的回答,但不行;)
它不会刷新以前的视图...

我想如果它的状态发生了变化,它应该刷新它。 所以在刷新中设置一些随机值

2016 年 4 月 9 日 09:51,rtrompier [email protected]写道:

感谢您的回答,但不行;)
它不会刷新以前的视图...


您收到此消息是因为您订阅了此线程。
直接回复本邮件或在GitHub上查看https://github.com/aksonov/react-native-router-flux/issues/465#issuecomment -207737400

谁能告诉我如何在 Actions.pop() 之后刷新?

同样,您必须更改要刷新的先前组件的状态。 这就是 NavigationExperimental API 的工作原理。

@aksonov我遇到了与@helloworld123456@rtrompier相同的问题。 我的导航流程如下所示:

场景 A => 场景 B => 场景 C

当我从 C 弹出到 B 时,我需要重新渲染场景 B。我看到@Elyx0建议使用Actions.pop(); Actions.refresh();我有两个问题:

  1. 调用Actions.refresh()渲染场景 C 还是 B?
  2. 是否可以覆盖导航栏中后退按钮的onPress处理程序? 查看代码后,似乎不可能。
  1. 它应该刷新B,但你为什么不测试它并找出答案!
  2. 使用renderBackButton传入您自己的后退按钮、自定义 onPress 等。

明白了 - 谢谢@cridenour

@samdturner你能告诉我怎么做吗?

谢谢

@alfan2305

Actions.pop();
Actions.refresh();

navBar呢? 我们不应该在refresh=true上有一个Scene 。 否则,我必须覆盖onPressbackButton来调用上述两个电话的功能。

@ssomnoremac覆盖按钮有什么问题? 做起来很简单。 如果这个问题更受欢迎,我会说我们添加了功能,但它似乎是一个边缘情况。

@cridenour我相信能够在路线更改时重新渲染场景超出了这个问题的范围。 在我的情况下,我想从注册序列返回并通过在重新渲染时触发操作而不是将重置挂接到后退按钮来重置我的 Redux 存储中的注册状态。 有没有更好的方法来实现这一点?

我认为您的注册组件会通过聆听 redux 来接收更改,不是吗? 或者当另一个组件位于顶部时,场景在收到新道具后没有重新渲染的问题?

我的意思是我们提供一个onBack所以在定义注册场景时应该像

const refreshOnBack = () => { Actions.pop(); Actions.refresh(); }

...
<Scene key="registration" component={Registration} onBack={refreshOnBack} />
...

谢谢,我不知道onBack因为我使用detailExample作为我的文档。

没问题。 一定要浏览一下 https://github.com/aksonov/react-native-router-flux/blob/master/docs/API_CONFIGURATION.md 因为当你“离开书本”时有很大的灵活性:)

大家好,
首先:感谢大家的见解,它们非常有用,因为我是 React 和 javascript 编码的新手。

我只是尝试了从@cridenour了“refreshOnBack”解决方案:不幸的是我在一些困难绊倒了。

现在按钮什么都不做。 即使按钮突出显示,我也只是停留在我的“C”场景(参考@ssomnoremac示例)。 如果我只是设置:
const refreshOnBack = () => { Actions.pop(); }
我没有更新我的父视图的预期行为。

我错过了什么? :/

我的结果与@Brokray相同

如果您远程调试,您是否在控制台中看到错误?

@cridenour控制台中没有错误。
有什么我可以登录到控制台来弄清楚发生了什么的吗? 也许是减速机的东西?
减速器对我来说仍然有点神秘。

谢谢。

唔! 也许尝试先刷新。

Actions.refresh({key: 'yourSceneKey'}); Actions.pop();

感谢您的帮助@cridenour :我刚刚尝试了您的想法,但不幸的是它也不起作用。 我从 C 到 B 没有任何问题,但“B”没有改变。
似乎问题来自refresh()方法:即使我在“B”场景上放了一个刷新按钮(调用Actions.refresh() )也没有任何反应。

@jholton我不知道它是否可以帮助您,但是:我找到了一种自定义方法来更新我的场景:
我为每个场景(B 和 C)都有一个减速器,当我在“C”中调用我的POST动作时,我的两个减速器都接到了调用,C 执行他需要做的事情,而 B 设置了一个状态变量'更新'到true
这样,在 B 的“ComponentWillReceiveProps”中,我测试了“更新”,并再次调用刷新场景所需的内容。

如果有人对Actions.refresh()问题有更多见解,请不要犹豫!
谢谢。

@Brokray有趣的是它不起作用 - 但无论如何你有更好的解决方案。 我不相信尝试使用导航系统来传递应用程序状态 - 我总是坚持使用通量商店。

@Brokray如果不是太麻烦,你能举个例子吗? 你如何为单个场景使用减速器? 我已经阅读了所有文档,但在这一点上我有点不知所措。

@cridenour是的,我不想传递应用程序状态本身。 我只想重新渲染场景 B。
在场景 B 中,我按数据库显示一些数据。 在场景 C 中,我有一个向数据库添加数据的表单。 当用户弹回场景 B 时,我只想触发所有生命周期方法(例如 getInitialState、componentWillMount 等),以便检索和显示新添加的数据。 这些生命周期方法不会触发。

@jholton正确,这是 React 的设计,无论好坏。 我强烈建议您尝试使用 Flux 实现(很多人喜欢 redux,我个人使用 Alt)并在那里管理数据。 这样,当您更新数据时,组件将重新渲染(这意味着重新运行render() )并且不依赖于组件的初始化。 一旦将数据层从组件中移开(它们只是读取数据并显示),React 中的许多反应问题就会变得容易得多。

也就是说, Actions.refresh() 只会导致新的道具和重新渲染(同样,只是render() ),但不会调用 componentWillMount 等。

@jholton好吧,正如@cridenour所说,我使用了一个flux 实现(确实是redux),它允许您通过操作、状态和reducer 来管理您的数据。 一旦您熟悉了通量实现,我将很乐意为您提供一个示例!
@cridenour再次感谢您的帮助!

@Brokray是的,我现在正在研究 Redux 教程。 当我可以更智能地讨论通量/redux 时,我将重新访问此线程。 谢谢。

我会成功更新道具但是当我尝试再次移动到下一个视图时它给了我错误
这段代码写在我的设置屏幕上
Actions.pop();
Actions.refresh({key: 'pageOne', name:'wwwww'});

只有这样才能工作并更新视图,但是当我再次尝试转到设置屏幕时,它给了我错误
screen shot 2016-08-02 at 4 43 38 pm

我最终会通过在延迟后使用道具调用空刷新来解决它吗
Actions.popTo('pageOne');
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

@washaq :这对我

Actions.pop(); Actions.refresh();
只是刷新页面,但不会转到上一个场景。

如果 Actions 方法可以基于承诺这样你可以将它们链接在一起,那就太好了

Actions.pop().then(Actions.refresh()).

或者

Actions.pop().refresh()

@israrhnrtech@tuneZola如果你想调用之前的刷新,它不起作用,那么你需要在延迟后调用它,然后它会像那样正确调用

Actions.pop();
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

首先感谢回复@tuneZola@washaq
动作('pageOne');
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

这段代码运行良好..
再次感谢 ..

@israrhnrtech没问题,伙计,我发现真的很多命中和追踪,它看起来很简单,但是当你的新手反应原生并且不知道如何做到这一点时,它的故事就不同了:)

我在我的场景中面临同样的问题:

A => B

在 BI 上更改我的 redux 存储状态,但是当我执行Router.pop() ,不会在 A 上触发 componentWillReceiveProps。

我的 router.pop 本地存在于 B 页面内(不使用默认导航栏),所以

Router.pop()
Router.refresh()

不起作用,设置超时也不起作用,有关如何实现这一目标的任何想法?

我只会在您传递要更改的道具时更新,即

Actions.pop();
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

在这个我在我的主视图中将名称作为道具传递,这意味着如果我使用this.props.name来更新文本然后它被更新,你需要将更新状态作为刷新中的道具传递,因为这就是视图知道它更新的方式。
希望能帮到你

对我来说,这有效:
navigator.replacePreviousAndPop(previousRoute);

@phpscrpt ,你能简要介绍一些它是如何工作的代码吗?

@israrhnrtech抱歉,它用于 react-native 内置的 Navigator 组件。 如果 react-native-router-flux 以某种方式从 Navigator 组件继承,它可能会起作用。

@washaq超时解决方案,如下所示,对我不起作用:

返回并刷新(){

Actions.pop();
setTimeout(() => {
Actions.refresh({name:'zzzzar'});
console.log("zzzz");
}, 10);

}

返回并刷新

我要刷新的页面上的 componentDidMount 没有被调用。

我错过了什么吗?

谢谢!

@ivansifrim您是否找到了解决方案?
我们也在尝试找到一种在登陆屏幕后触发动作的方法

这对我有用: Actions.pop({ refresh: {} });
它弹出当前屏幕并刷新父屏幕。

@JeroenNelen - 我还没有,但我会尝试@Bertjuhh 的建议

提到的问题有什么解决方案吗?

这对我来说效果很好:

const refreshOnBack = () => { Actions.pop({ refresh: {} }); }
...
// child scene
<Scene key="settings" component={SettingsScreen} onBack={refreshOnBack}/>
...

在我最近完成的一个简单应用程序中,我已经解决了这个问题(此代码位于导出上方的路由器文件中):

Actions.pop = () => Actions.NAME_OF_PREVIOUS({ type: ActionConst.RESET });

您必须在用于覆盖pop的函数中执行一些条件逻辑。 在我的情况下工作得很好(当然我不介意使用ActionConst.RESET时的备用后退过渡)。 快n讨厌。

终于有什么可以正常工作的了吗? 上述提议都没有真正奏效......

+1

@ivansifirm它应该是最后一次使用它我记得在刷新传递中你想要取消日期的道具即“名称”上方是我希望你在我以前的视图中更新的道具

同样的问题在这里,很奇怪。
有时它有效,有时它不起作用。

这是我的代码。 (在我的例子中,有场景 A 和 B,A=>B 通过导航,B=>A 通过弹出)

场景一:
componentWillReceiveProps(nextProps) { if (this.props.test !== nextProps.test) { this._getUser() // I need call this func after pop } }
场景B

NavigationActions.pop({refresh:{test:true}})

我怎么了?
谢谢。

NavigationActions.pop({refresh:{test:true}})

你能把它改成

NavigationActions.pop({refresh:{test:!test}})

2017 年 6 月 20 日,星期二,晚上 7:29,MobileStar通知@ github.com
写道:

同样的问题在这里,很奇怪。
有时它有效,有时它不起作用。

这是我的代码。 (在我的例子中,有场景 A 和 B,A=>B 通过导航,
B=>A 通过弹出)

场景一:

componentWillReceiveProps(nextProps) {
如果 (this.props.test !== nextProps.test) {
this._getUser() // 我需要在 pop 之后调用这个函数
}
}

场景B

NavigationActions.pop({refresh:{test:true}})

我怎么了?
谢谢。


您收到此消息是因为您订阅了此线程。
直接回复本邮件,在GitHub上查看
https://github.com/aksonov/react-native-router-flux/issues/465#issuecomment-309945049
或静音线程
https://github.com/notifications/unsubscribe-auth/AExqB3CZM4U1yuwKslfuBj88uVVJulGtks5sGIAbgaJpZM4H_0pN
.

@nikitph感谢您的帮助。
是的,我试过了。
但是 componentWillReceiveProps 并不总是在弹出后触发。
您能否让我知道 componentWillReceiveProps 何时被触发,或者在 pop 之后是否触发了其他生命周期函数?
问候。

@SelfnessAid啊,现在我记得我为什么放弃解决这个问题了。 我有一个类似的问题。 “但 componentWillReceiveProps 并不总是在弹出后触发。” 我想我已经解决了这个问题,因为我在目标页面上拥有一个可滑动视图的索引来驱动刷新。 是的,这很糟糕,但我正在解决我的问题。

我想通了一些。 我真的不认为它是干净的,但对我来说它可以完成工作,所以就在这里。 (我正在使用 Redux 来做到这一点)

每当我执行Action.scene()Action.pop()时,我都需要调用一个 fetch 函数。 这个 fetch 最初是在 componentWillMount 方法中调用的,但是因为它在使用Action.pop()时没有被调用,所以我将所有的Action.scene()Action.pop()调用更改为 2 个自定义函数,这些函数是操作意味着我拥有比平时更多的 redux 容器,但是 :/. 所以他们在这里:

const goTo = (scene, label, sceneParams = {}, pushed = true) => ( // Equivalent of `Action.scene()`
   (dispatch) => {
     dispatch(setAppLabel(scene, label, sceneParams, pushed)); // I'm storing some infos about the scene in my store. Will be used in custom `pop()` later.
     mapSceneToAction(scene, dispatch, sceneParams); // // Calls the function initially used in the componentWillMount. I'll show a sample further
     Actions[scene](sceneParams);
   }
);

const pop = () => (  // Equivalent of `Action.pop()`
   (dispatch, getState) => {
     Actions.pop();
     mapSceneToAction(getState().sceneReducer.previousScene, dispatch, getState().sceneReducer.previousScene.itemProps); // Retrieving some infos stored in the store during `goTo()`
   }
);

这是 mapSceneToAction() 的样子:

const mapSceneToAction = (scene, dispatch, itemProps) => {
  switch (scene) {
    case 'events':
      dispatch(fetchEvents()); // Or any other action :P
      break;
    case 'anyScene':
      dispatch(anyAction(withAnyParams));
      break;
    default:
  }
};

它有点棘手,很重,可能不是很干净,但是由于我使用了这种方法,因此我设法解决了我遇到的所有问题。

将函数道具传递给下一个场景..
Actions.YourRoute({ onPress: () => setState.. });

然后在下一个场景中,调用函数 prop
this.props.onPress();

@ bethuel11这是在循环中重新渲染组件。 虽然不是一个好的解决方案

我发现了一个简单的技巧...

当前状态/当前页面 =>

Actions.pop();
setTimeout(() => {
动作.刷新({
isRefresh: 真,
});
}, 0);

上一个状态/页面 => 内部渲染添加以下条件,

如果(this.props.isRefresh){
动作.刷新({
isRefresh: 假,
});
//如果你在这里调用设置状态,它会自动重新渲染自己...
this.setState({isloading:true});

谢谢。
}

此页面是否有帮助?
0 / 5 - 0 等级