美文网首页
ReactNative 组件间通讯

ReactNative 组件间通讯

作者: Android_冯星 | 来源:发表于2018-08-28 17:37 被阅读0次

参考文章
参考

子组件传递参数到父组件 (回调)

  1. 在父组件中定义一个带参数的方法
getProductPrice(price) {
        this.setState({
            price
        });
    }

price就是最后回调的参数。设置给state就会刷新父组件的视图。

  1. 在父组件中使用子组件 并设置参数getProductPrice
<ProductItem getProductPrice={(price)=>this.getProductPrice(price)}></ProductItem>

参数price就是回调回来的参数。

  1. 在子组件中调用
componentDidMount() {
        AsyncStorage.getAllKeys((err, keys) => {
            console.log(keys);
            if (err) {
                alert(err);
            }
            AsyncStorage.multiGet(keys, (err, result) => {
                console.log('result : ' + result);
                let arr = [];
                let price = 0;
                for (let i in result) {
                    arr.push(JSON.parse(result[i][1]));
                    price += JSON.parse(result[i][1]).price;
                }
                this.setState({
                    arr,
                    price
                });
                this.props.getProductPrice(price);
            });
        });
    }

getProductPrice回存在props属性中,把price传进入,最后就可以在父控件中拿到该参数。

父控件调用子组件的函数(ref属性)

1.父控件定义ref属性

<ProductItem getProductPrice={(price)=>this.getProductPrice(price)} ref={(ProductItem)=>{this.refProductItem = ProductItem}}></ProductItem>

ref属性指定的就是ProductItem组件。

2.在子组件中定义函数

clear() {
        this.setState({
            arr: [],
            price: 0,
        });
    }

在子组件中定义了一个清除的方法。这个可以随便定义的。

  1. 最后在父组件中使用ref属性调用子组件中定义的方法
this.refProductItem.clear();

这样就会调用子组件中的函数了。

navigation传递函数

React Navigation中文网

事故现场:有3个界面ABC,A页面开启B,B界面开启C,现在 C的逻辑处理完毕,需要传递B参数,并刷新视图。

  1. B在开启C页面传递一个函数
<TouchableOpacity onPress={()=>this.props.navigation.navigate('SettlementUi',{fetchData:()=>{this.setState({count:0})}})}>
    <Text style={styles.btn}>去结算{str}</Text>
</TouchableOpacity>

B页面开启C页面并传递一个函数,函数的内容是重置count,然后刷新视图。

  1. 在C界面拿到fetchData函数并调用。
clearProduct = () => {
        AsyncStorage.clear();
        this.setState({
            price: 0,
            arr: [],
        });
        this.refProductItem.clear();
        //      this.props.fetchData();
        const {
            goBack,
            state
        } = this.props.navigation

        state.params.fetchData();
        //      goBack();
    }

在C界面的this.props.navigation拿到state,传递的参数就放在state.params中,取到函数就可以直接调用了。我这里还去了goBack函数。回退页面并刷新视图。

代码

HomeUi.js
import React, {
    Component
} from 'react';


import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    Image,
    AsyncStorage,
    TouchableHighlight,
} from 'react-native';


import {
    createStackNavigator
} from 'react-navigation';

import SettlementUi from './SettlementUi';

const datas = [{
    id: 1,
    title: '泥猴桃1',
    desc: '12个装',
    price: 99,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
    id: 2,
    title: '泥猴桃2',
    desc: '12个装',
    price: 299,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
    id: 3,
    title: '泥猴桃3',
    desc: '12个装',
    price: 399,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
    id: 4,
    title: '泥猴桃4',
    desc: '12个装',
    price: 499,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
    id: 5,
    title: '泥猴桃5',
    desc: '12个装',
    price: 599,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}, {
    id: 6,
    title: '泥猴桃6',
    desc: '12个装',
    price: 699,
    url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'
}];

export default class HomeUI extends Component {

    //<Image style={{flex:1,borderWidth: 1, borderColor: '#f00'}} source={{uri:'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg'}} ></Image>
    render() {

        return (
            <List navigation={this.props.navigation}></List>
        );
    }
}


class Item extends Component {

    static defaultProps = {
        title: 'https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png',
        url: '默认的标题',
    };

    static propTypes = {
        title: React.PropTypes.string.isRequired,
        url: React.PropTypes.string.isRequired,
    };
    /**
        {
            url:xxx,
            text:xxx,
            press:xxx,
        }
    */
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <View style={styles.item_root}>
                 <TouchableOpacity style={styles.container} onPress={this.props.press}>
                    <Image resizeMode='contain' style={styles.images}  source={{uri:this.props.url}}>
                        <Text numberOfLines={1} style={styles.desc} > {this.props.title}</Text>
                    </Image>
                </TouchableOpacity>
            </View>
        );
    }
}


class List extends Component {

    constructor(props) {
        super(props);
        this.state = {
            count: 0,
        };
    }

    clear() {
        this.setState({
            count: 0,
        });
    }

    press = (data) => {
        this.setState({
            count: this.state.count + 1
        });

        AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function(err) {
            if (err) {
                alert(err);
            } else {
                console.log('成功' + JSON.stringify(data));
            }
        });

    }

    //生成随机ID:GUID 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符
    //GUID生成的代码来自于Stoyan Stefanov

    genId() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            let r = Math.random() * 16 | 0,
                v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }).toUpperCase();
    }

    componentDidMount() {
        let _that = this;
        AsyncStorage.getAllKeys((err, keys) => {
            console.log(keys);
            if (err) {
                console.log(err);
            } else {
                console.log('读取成功了的个数:' + keys.toString());
            }

            _that.setState({
                count: keys.length
            }, () => {
                console.log(_that.state.count);
            });
        });
    }

    render() {
        let list = [];
        for (let i in datas) {
            if (i % 2 === 0) {
                list.push(
                    <View style={styles.item} key={i}>
                            <Item url={datas[i].url} title={datas[i].title} press={this.press.bind(this,datas[i])}></Item>

                            <Item url={datas[parseInt(i)+1].url} title={datas[parseInt(i)+1].title} press={()=>this.press(datas[parseInt(i)+1])}></Item>
                    </View>
                );
            }
        }
        let count = this.state.count;
        let str = null;
        if (count) {
            str = ',共' + count + '件商品!';
        }
        return (
            <View>
                {list}
                <TouchableOpacity onPress={()=>this.props.navigation.navigate('SettlementUi',{fetchData:()=>{this.setState({count:0})}})}>
                    <Text style={styles.btn}>去结算{str}</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    btn: {
        marginTop: 10,
        textAlignVertical: 'center',
        height: 30,
        textAlign: 'center',
        marginRight: 5,
        marginLeft: 5,
        borderRadius: 5,
        backgroundColor: '#FF7200',
        color: '#fff',
        fontSize: 18,
    },
    item_root: {
        flex: 1,
        height: 100,
    },
    item: {
        flexDirection: 'row',
        marginBottom: 10,
    },
    images: {
        flex: 1,
        borderWidth: 1,
        margin: 5,
        backgroundColor: 'transparent',
        borderRadius: 5,
        flexDirection: 'column-reverse',
    },
    desc: {
        backgroundColor: "#0008",
        height: 25,
        color: '#fff',
        textAlign: 'center',
        lineHeight: 20,
        textAlignVertical: 'center',
        opacity: 0.7,
    },
});
SettlementUi.js
import React, {
    Component
} from 'react';

import {
    View,
    StyleSheet,
    Text,
    AsyncStorage,
    TouchableOpacity,
    ScrollView,
} from 'react-native';

const styles = StyleSheet.create({
    btn: {
        marginTop: 10,
        textAlignVertical: 'center',
        height: 30,
        textAlign: 'center',
        marginRight: 5,
        marginLeft: 5,
        borderRadius: 5,
        backgroundColor: '#FF7200',
        color: '#fff',
        fontSize: 18,
    },
    container: {
        flexDirection: 'row',
        margin: 5,
        borderRadius: 5,
        borderWidth: 1,
        borderColor: '#dddddd',
        justifyContent: 'space-between',
    },
    text: {
        marginLeft: 10,
        marginRight: 10,
    }
});

class ProductItem extends Component {

    constructor(props) {
        super(props);
        this.state = {
            arr: [],
            price: 0,
        }
    }

    clear() {
        this.setState({
            arr: [],
            price: 0,
        });
    }

    componentDidMount() {
        AsyncStorage.getAllKeys((err, keys) => {
            console.log(keys);
            if (err) {
                alert(err);
            }
            AsyncStorage.multiGet(keys, (err, result) => {
                console.log('result : ' + result);
                let arr = [];
                let price = 0;
                for (let i in result) {
                    arr.push(JSON.parse(result[i][1]));
                    price += JSON.parse(result[i][1]).price;
                }
                this.setState({
                    arr,
                    price
                });
                this.props.getProductPrice(price);
            });
        });
    }

    render() {
        let datas = this.state.arr;
        let list = [];
        for (let i in datas) {
            console.log(datas);
            let str = datas[i].title + '号产品,' + datas[i].desc;
            list.push(
                <View style={styles.container} key={i}>
                    <Text style={styles.text}>{str}</Text>
                    <Text style={styles.text}>{datas[i].price}</Text>               
                </View>
            );
        }
        return (
            <View>
                {list}
            </View>
        );
    }
}


export default class SettlementUi extends Component {

    constructor(props) {
        super(props);
        this.state = {
            price: 0,
        }
    }

    getProductPrice(price) {
        this.setState({
            price
        });
    }

    clearProduct = () => {
        AsyncStorage.clear();
        this.setState({
            price: 0,
            arr: [],
        });
        this.refProductItem.clear();
        //      this.props.fetchData();
        const {
            goBack,
            state
        } = this.props.navigation

        state.params.fetchData();
        //      goBack();
    }
    render() {
        return (
            <ScrollView>
                <ProductItem getProductPrice={(price)=>this.getProductPrice(price)} ref={(ProductItem)=>{this.refProductItem = ProductItem}}></ProductItem>

                <TouchableOpacity>
                    <Text style={styles.btn}>共支付,{this.state.price}</Text>
                </TouchableOpacity>

                <TouchableOpacity  onPress={()=>this.clearProduct()}>
                    <Text style={styles.btn}>清空购物车</Text>
                </TouchableOpacity>
            </ScrollView>
        );
    }
}

相关文章

  • ReactNative 组件间通讯

    参考文章参考 子组件传递参数到父组件 (回调) 在父组件中定义一个带参数的方法 price就是最后回调的参数。设置...

  • reactNative组件通信

    reactNative组件通信 分为两种第一种: 父组件向子组件通讯第二种:是子组件向父组件通讯 父组件向子组件通...

  • angular4学习笔记整理(四)组件间通讯、管道

    之后的笔记就写的快一点 组件间通讯 1.组件间通讯 。父组件向子组件输入属性用 子组件声明接收父组件的属性@in...

  • React Native联系人组件

    本文原创首发于公众号:ReactNative开发圈,转载需注明出处。 React Native通讯录联系人组件,名...

  • vue 组件间通讯

    总结起来三种方式 一、eventbus bus.js component1.vue component2.vue ...

  • 组件间通讯方式

      组件化,在工程组成结构角度讲,也可称为模块化。最终目的是为了解藕。  本文总结了组件间交互方式及原理,不涉及到...

  • Vue 组件间通讯

    最近回顾前端,先是 React 现在因工作需又要开始 vue 了。开发过程中多半时间我们需要结构,有层次有上下级,...

  • vue组件间通讯

    父子 $emit/on props $parent/children $attrs/listenner $ref ...

  • Vue组件间通讯

    Vue中组件通讯的方式有很多种,每一种应用的场景可能都有一些不一样,我们需要在合适的场景下选择合适的通讯方式。 父...

  • Vue中组件通信(eventBus)

    在vue项目中,父子组件间的通讯很方便。但兄弟组件或多层嵌套组件间的通讯,就会比较麻烦。这时,使用eventBus...

网友评论

      本文标题:ReactNative 组件间通讯

      本文链接:https://www.haomeiwen.com/subject/yzcqwftx.html