首页 文章

在兄弟视图之间反应Native Pass数据

提问于
浏览
16

我正在使用React Native开发一个简单的待办事项列表应用程序,我的问题如下:我的项目根目录中有一个NavigatorIOS,一个包含ListView作为初始路由的组件,以及一个导致任务创建视图 .

创建新任务后,将弹出视图以显示ListView . 我正在尝试将新创建的任务添加到此ListView(其数据源包含在组件状态中) .

How to perform such an operation, what's the good practice? 我会在纯本机应用程序中使用委托,但在这里,两个视图都由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 .

2 回答

  • 15

    React-Native文档简要介绍了communicating between components的方法 .

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

    • Manager pattern . 对于真正的兄弟姐妹< - >兄弟通信(即两个兄弟姐妹通过作曲共享父母),您可以让父母管理该州 . 例如,您可能有 <MyConsole> 窗口小部件,其中包含 <TextInput><ListView> ,其中包含用户的过去输入,两者都是 <Console> 窗口小部件的子项 .

    • 这里, <Console> 可以充当经理 . 当 <TextInput> 更改其值时,您可以使用onChangeText事件将新值传递给父 <MyConsole> 组件,然后更新其状态并将其传递给其子项 .

    • Event (publish-subscribe) pattern . 请记住,组件只是对象,因此您可以使用面向对象的方法在组件之间进行通信 . React文件指出:

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

    • 在这里,您可以使用像pubsub.js这样的简单发布 - 订阅库,这样当一个组件发生更改时,只需发布更改,其他相关组件可以监听事件并自行更新 . 这对于较小的应用程序来说是一种非常有效的方法

    • Flux pattern . 纯发布/订阅系统的缺点之一是,难以跟踪状态 . 例如,如果你有两个组件(例如EditTitle,EditBody),它们都可以像电子邮件一样更新某些状态,那么纯粹的事件系统最终会传递不同版本的状态,因为没有"single version of the truth",所以可能会因冲突而混乱 . 这就是React的flux approach所在 . 使用flux,组件更新数据存储,负责更新和协调数据(例如 EmailDataStore ),然后存储通知组件更新状态 .

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

    在设置订阅时,最好在组件安装后添加订阅,并在组件卸载之前明确删除它们(否则最终会有大量的孤立订阅) .

  • 0

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

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

相关问题