React Native 在兄弟视图之间传递数据
Posted
技术标签:
【中文标题】React Native 在兄弟视图之间传递数据【英文标题】:React Native Pass data between sibling views 【发布时间】:2015-06-19 18:04:37 【问题描述】:我正在使用 React Native 开发一个简单的待办事项列表应用程序,我的问题如下:我的项目根目录中有一个 Navigatorios,其中包含一个包含 ListView 作为初始路由的组件,以及一个导航栏按钮导致任务创建视图。
一旦创建了新任务,视图就会弹出以显示 ListView。我正在尝试将我新创建的任务添加到此 ListView(其数据源包含在组件状态中)。
如何执行这样的操作,有什么好的做法?我会在纯原生应用程序中使用委托,但在这里,两个视图都由 NavigatorIOS 实例处理。
index.ios.js
addTask()
console.log("Test");
,
render()
return (
<React.NavigatorIOS
ref="nav"
style=styles.container
tintColor="#ED6063"
initialRoute=
title: "Tasks",
component: TasksList,
rightButtonTitle: 'Add',
onRightButtonPress: () =>
this.refs.nav.navigator.push(
title: "New task",
component: NewTask,
passProps:
onTaskAdded: this.addTask
,
leftButtonTitle: "Cancel"
);
/>
);
NewTask.js
taskAdded()
console.log("Added: " + this.state.title + " - " + this.state.description);
this.props.onTaskAdded(
title: this.state.title,
description: this.state.description
);
this.props.navigator.pop();
TasksList.js
var dataSource = new ListView.DataSource(
rowHasChanged: (r1, r2) => r1 !== r2
);
this.state =
dataSource: dataSource.cloneWithRows(data)
;
您可以找到complete source code here。
【问题讨论】:
【参考方案1】:React-Native 文档有一个关于communicating between components 方法的简短部分。
当您尝试做一些比父->子或子->父关系更复杂的事情时,有几种选择:
经理模式。对于真正的兄弟兄弟通信(即两个兄弟姐妹通过组合共享父节点),您可以让父节点管理状态。例如,您可能有一个 <MyConsole>
小部件,它有一个 <TextInput>
和一个包含用户过去输入的 <ListView>
,它们都是 <Console>
小部件的子级。
<Console>
可以充当经理。当 <TextInput>
更改其值时,您可以使用 onChangeText
事件将新值传递给父 <MyConsole>
组件,然后它会更新其状态并将其传递给其子组件。
事件(发布-订阅)模式。请记住,组件只是对象,因此您可以使用面向对象的方法在组件之间进行通信。 React 文档指出:
在这里,您可以使用像pubsub.js 这样的简单发布-订阅库,这样当一个组件发生更改时,它只会发布更改,而其他相关组件可以侦听事件并自行更新。对于小型应用来说,这可能是一种非常有效的方法。对于没有父子关系的两个组件之间的通信,可以设置自己的全局事件系统。在 componentDidMount() 中订阅事件,在 componentWillUnmount() 中取消订阅,并在收到事件时调用 setState()。
通量模式。纯发布/订阅系统的缺点之一是,很难跟踪状态。例如,如果您有 2 个组件(例如 EditTitle、EditBody),它们都可以像电子邮件消息一样更新某些状态,那么纯事件系统最终会传递不同版本的状态,这可能会因冲突而变得混乱,因为没有“单一真相版”。这就是 React 的 flux approach 的用武之地。使用 Flux,组件更新负责更新和协调数据的数据存储(例如 EmailDataStore
),然后存储通知组件更新状态。
TasksDataStore
发布更新(例如,通过发布或直接函数调用),然后可能会向其订阅者发布tasks-updated
之类的事件。任务面板和结果面板都将订阅数据存储。
在设置订阅时,最好在组件挂载后添加订阅,并在组件卸载之前将其删除(否则您最终会得到很多孤立的订阅)。
【讨论】:
tks @tohster,你是对的,建立一个全局事件系统是最好的方法,但我是 react-native 的新手,我不知道如何在反应原生。【参考方案2】:您应该重写您的constructor
函数以动态方式获取数据。然后当页面重新加载时,它将获得包含新任务的正确数据。在这里,您从一个不会改变的静态数组中获取数据。
将任务列表保存到本地文件或Firebase,构建时读取。
【讨论】:
所以你建议使用某种巨大的全局变量/区域在视图之间传递数据?这听起来像是非常糟糕的架构...... @Blackus 不然怎么弄到任务列表? “全局”是可选的。 这正是这里的重点。在开发原生时,我们可以使用协议或传递代码块来执行(如回调)。所以任务列表只与这两个视图“共享”,与其他事物并没有很大的共同点。 @Blackus 您可以将列表作为道具传递到下一个视图。以上是关于React Native 在兄弟视图之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式在视图控制器之间传递数据?我想将我的UITextfield数据传递给另一个视图控制器[重复]