16

我正在使用 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"
                        });
                    }
                }}/>
        );
    }

新任务.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();
}

任务列表.js

var dataSource = new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
    dataSource: dataSource.cloneWithRows(data)
};

您可以在此处找到完整的源代码

4

2 回答 2

15

React-Native 文档有一个关于组件间通信方法的简短部分。

当您尝试做一些比父->子或子->父关系更复杂的事情时,有几个选项:

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

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

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

    • 在这里,您可以使用一个简单的发布-订阅库,例如pubsub.js,这样当一个组件发生更改时,它只会发布更改,而其他相关组件可以监听事件并自行更新。对于较小的应用程序,这可能是一种非常有效的方法。
  3. 通量模式。纯发布/订阅系统的缺点之一是,很难跟踪状态。例如,如果您有 2 个组件(例如 EditTitle、EditBody),它们都可以像电子邮件消息一样更新某些状态,那么纯事件系统最终会传递不同版本的状态,这可能会因冲突而变得混乱,因为没有“单一真相版”。这就是 React 的通量方法的用武之地。通过通量,组件更新负责更新和协调数据(例如EmailDataStore)的数据存储,然后存储通知组件更新状态。

    • 因此,在您的示例中,任务视图将向 a 发布更新(例如,通过发布或直接函数调用) ,然后它可能会像其订阅者TasksDataStore一样发布事件。tasks-updated任务面板和结果面板都将订阅数据存储。

设置订阅时,最好在组件挂载之后添加订阅,并在组件卸载之前将其删除(否则您最终会得到很多孤立的订阅)。

于 2015-10-09T16:10:25.780 回答
0

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

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

于 2015-10-04T02:14:49.173 回答