2015-04-14 13 views
16

我正在开发一个使用React Native的简单待办事项列表应用程序,我的问题如下:我的项目根目录中有一个NavigatorIOS,其中包含一个包含ListView的组件路线和一个导航栏按钮,导致任务创建视图。在同级视图之间React Native Pass数据

一旦创建了新任务,视图就会弹出,以便显示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

回答

0

您应该重写您的constructor函数以从动态方式获取数据。然后当页面重新加载时,它会得到一个包含新任务的正确数据。在这里你从一个静态数组中获得数据,这个数组不会改变。

将任务列表保存到本地文件或Firebase,并在构建时读取。

+0

所以你建议用某种巨大的全局变量/面积与视图之间传递数据?这听起来像极坏的架构...... – Blackus

+0

@Blackus否则,你如何获得任务列表? “全球”是可选的。 – KChen

+0

这里就是这一点。在开发本机时,我们可以使用协议或传递代码块来执行(如回调)。所以任务列表只与这两个视图“共享”,它与其他事物并不存在很大的共同点。 – Blackus

15

React-Native文档包含有关communicating between components方法的简要部分。

当你试图做一些事情比父 - >儿童或儿童安全>父母关系比较复杂,有几个选项:

  1. 管理模式。对于真正的兄弟姐妹< - >兄弟姐妹通信(即两个兄弟姐妹通过组合共享父母的地方),您可以让父母管理该状态。例如,您可能有一个<MyConsole>小部件,其中包含<TextInput><ListView>,其中包含用户过去的输入,它们都是<Console>小部件的子项。

    • 在这里,<Console>可以充当经理。当<TextInput>更改其值时,可以使用onChangeText事件将新值传递给父代<MyConsole>组件,该组件将更新其状态并将其传递给子组件。
  2. 事件(发布 - 订阅)模式。请记住,组件只是对象,因此您可以使用面向对象的方法在组件之间进行通信。 React文档注意:

    对于没有父子关系的两个组件之间的通信,您可以设置您自己的全局事件系统。在收到事件时,订阅componentDidMount()中的事件,取消订阅componentWillUnmount(),并调用setState()。

    • 在这里,你可以像使用pubsub.js一个简单的发布 - 订阅库,这样,当一个组件改变它只是出版的变化和其他相关部件可以监听的事件和自我更新。这对小型应用程序来说可能是一种非常有效的方法
  3. 通量模式。纯粹的发布/订阅系统的一个缺点是,跟踪状态变得困难。举例来说,如果你有2个组件(例如EditTitle,EditBody),它可以同时更新如电子邮件消息的一些状态,那么一个纯粹的事件系统最终通过不同的版本状态的周围会导致混乱与冲突,因为没有“单版本的真相“。这是阵营的flux approach用武之地。用焊剂,部件更新的数据存储器,其负责更新和协调数据(例如EmailDataStore),并且在商店然后通知更新的状态的部件。

    • 因此,在你的榜样,任务视图将发出一个更新(例如通过发布或直接函数调用)的TasksDataStore,那么这可能会发布一个事件像tasks-updated它的用户。任务面板和结果面板都会订阅数据存储。

当设置订阅,这是最好的组件坐骑后添加订阅和绝对分量卸装前删除它们(否则你最终得到了很多孤儿订阅)。

+0

TKS @tohster,你是对的,建立一个全球性的事件系统是最好的方式,但我是新来的反应本地的,我不知道如何使一个全球性的事件系统的反应本地。 – backslash112