[原]东方耀react native学习39-复杂的组件通讯三种方案

来源:互联网 发布:sqlserver bit 默认值 编辑:程序博客网 时间:2024/04/29 01:07

接着上节课的代码,从一个bug入手,透过问题去学习,大大提升学习效率
解决bug:组件pop之后,之前的组件没有更新?
例子:在购物车里清空了,但是pop之后,商品详情页并没有更新?
3.更新阶段
主要发生在用户操作之后或父组件有更新的时候,此时会根据用户的操作行为进行相应的页面结构的调整
componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
pop之后,数据已经改变了,但是之前的组件没什么变化,组件的数据不同步了,解决方案:
方案1:监听didfocus事件,focus到当前路由的时候重新加载数据
navigationContext.addListener(‘didfocus’, callback)来替代
关键代码:
componentWillMount() {
console.log(‘List—componentWillMount’);
let navigator = this.props.navigator;

    let callback = (event) => {        console.log(            'List : 事件类型',            {                route: JSON.stringify(event.data.route),                target: event.target,                type: event.type,            }        );    };    // Observe focus change events from this component.    this._listeners = [        navigator.navigationContext.addListener('willfocus', callback),        navigator.navigationContext.addListener('didfocus', callback),    ];}componentWillUnmount(){    console.log('List---componentWillUnmount');    this._listeners && this._listeners.forEach(listener => listener.remove());}

复制代码

更新去取数据不用放到componentDidMount,直接放到didfocus的回调即可 不太稳定 

方案2:参考第15讲视频Navigator参数传递:往下一个路由push的时候传递参数(一个回调),在组件pop之前先调用此回调刷新数据

关键代码:
navigator.push({
name: ‘GouWu’,
component: GouWu,
params: {

                fetchData: function () {                    console.log('启动fetchData里的方法了');                    AsyncStorage.clear(function (err) {                        if (!err) {                            _that.setState({                                count: 0,                            });                            alert('购物车已经清空');                        }                    });                }            }        })        这是在点击清空购物车之后,马上pop,同时去触发回调        clearStorage() {    let _that = this;    //触发一下回调 让数据同步    console.log('点击了清空购物车');    if (this.props.fetchData) {        console.log('点击了清空购物车----回调去影响List页面');        this.props.fetchData();    }    const { navigator } = this.props;    if (navigator) {        navigator.pop();    }}

复制代码

还有一种情况:在点击清空购物车之后,不马上pop,而是通过点击物理back键去触发回调
这个就要复杂很多,
错误做法:
const top = routers[routers.length - 1];
console.log(‘栈顶的路由—’+top.component);
if (top.component.props.fetchData) {
console.log(‘回调fetchData了’);
top.component.props.fetchData();
}
复制代码

错误原因【回复本帖可见】:
本帖隐藏的内容

route.component是一个class 而不是一个object instance ,在里面找props是不可能找得到的,
如果一定需要从route上找到instance,需要在renderScene里给render的东西指定ref
类似 route.ref = r} />,然后通过route.ref来访问,但注意不应该假设route.ref总是有值
一定要判断下 if(route.ref)

方案3:采用redux/event等方式完成跨组件通讯

社区主流还是redux,但是建议大家抛弃redux了,因为太繁琐了,我们马上有更方便的架构,来自nodejs社区的,不是前端的方案
RN官方并不提供这个方案,redux也不是官方的
涉及到十几个插件 核心是decorator 都是npm上的插件
主要是一种 前端后端 结构和风格一致 的思想,facebook的野心:学习一次,编写任何平台!
React Native支持web android ios win10 nodejs跑服务器端

注意:方案1不推荐,推荐方案2或3

0 0