React-NativeReact Native学习react-native开发

005-React-Native子组件修改父组件的几种方式,兄弟

2017-06-16  本文已影响658人  Time_情书

欢迎各位同学加入群:397885169,里面大神超多,会帮助解决各种问题。

本人提供 React-Native技术服务,坐标杭州余杭区文一西路智能小镇,限时周六周日,免费。


先来一个笑话<来自网络>:
客户被绑,蒙眼,惊问:“想干什么?”
对方不语,鞭笞之,客户求饶:“别打,要钱?”
又一鞭,“十万够不?”
又一鞭,“一百万?”
又一鞭。客户崩溃:“你们TMD到底要啥?”
“要什么?我帮你做项目,写代码的时候也很想知道你TMD到底想要啥!”



概念理解

1-:在每一个render函数内,最外层的组件相当于Parents-Component,而包含内的组件相当于Children-Component。
2-:Children-Component内部还可以嵌套使用Children-Component,而相当于嵌套Children-Component来说,外一层的Children-Component就是它的Parents-Component。
3-:两个层级相同的Children-Component组件,称为兄弟组件。

DeviceEventEmitter可以跨组件,跨页面进行数据传递,还有一些状态的修改。

-2:子组件修改父组件

-3:兄弟组件相互修改属性



Coding

使用时:

    <ParentToChildMsg name="父组件通过props属性修改子组件属性"/>
    <ParentToChildMsg name={this.state.parentMsg}/>


全部代码

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    DeviceEventEmitter
} from 'react-native';
import PostMsgUseDevToPar from './PostMsgUseDevToPar'
import PostCallMsgToPar from './PostCallMsgToPar'
import PostCallMsgToParAndMsg from './PostCallMsgToParAndMsg'
import ParentToChildMsg from './ParentToChildMsg'
import ChildOneMsg from './ChildOneMsg'
import ChildTwoMsg from './ChildTwoMsg'
import UseParStateOneComponent from './UseParStateOneComponent'
import UseParStateTwoChangePage from './UseParStateTwoChangePage'

export default class Msg extends Component {
    constructor(props){
        super(props);
        this.state={
            listenerMsg:'listenerMsg',
            callMsg:'callMsg',
            callMsgAndMsg:'callMsgAndMsg',
            parentMsg:'父组件通过props属性修改子组件属性,第二种方式:state-props',
            childToChildMsg:'此消息初始化,来自于父组件'
        }
    }

    componentDidMount() {
        //注意addListener的key和emit的key保持一致
        this.msgListener = DeviceEventEmitter.addListener('Msg',(listenerMsg) => {
            this.setState({
                listenerMsg:listenerMsg,
            })
        });

    }

    componentWillUnmount() {
        //此生命周期内,去掉监听
        this.msgListener&&this.msgListener.remove();
    }



    render() {
        return (
            <View style={styles.container}>
                   <ParentToChildMsg name="父组件通过props属性修改子组件属性,第一种方式"/>
                   <ParentToChildMsg name={this.state.parentMsg}/>

                    <Text>子修改父 第一种方式 DeviceEventEmitter:</Text>
                    <Text>{this.state.listenerMsg}</Text>
                    <PostMsgUseDevToPar  />

                    <Text>子修改父 第二种方式  CallBack无参数:</Text>
                    <Text>{this.state.callMsg}</Text>
                    <PostCallMsgToPar  onChangeMsg={
                        this.onMsgByCall
                    }/>

                    <Text>子修改父 第三种方式  CallBack有参数:</Text>
                    <Text>{this.state.callMsgAndMsg}</Text>
                    <PostCallMsgToParAndMsg  onChangeMsg={(msg)=>{
                        this.onMsgByCallAndMsg(msg)
                    } }/>


                    <ChildOneMsg  />
                    <ChildTwoMsg  />

                    <UseParStateOneComponent msg={this.state.childToChildMsg} msgByCallAndMsgToChild={
                       (msg)=> this.msgByCallAndMsgToChild(msg)
                    }/>
                    <UseParStateTwoChangePage msg={this.state.childToChildMsg}/>

            </View>
        );
    }

    onMsgByCall=()=>{
        this.setState({
            callMsg:'通过CallBack修改父组件状态值'
        })
    }


    onMsgByCallAndMsg=(msg)=>{
        this.setState({
            callMsgAndMsg:msg
        })
    }

    msgByCallAndMsgToChild=(msg)=>{
        this.setState({
            childToChildMsg:msg
        })
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems:'center',
    },
});


运行效果截图

msg.gif-140.3kBmsg.gif-140.3kB

关于DeviceEventEmitter一点点补充

DeviceEventEmitter可以用来跨组件,跨页面进行通信,使用方式非常简单。
在发出DeviceEventEmitter的页面或者组件中使用emit():

DeviceEventEmitter.emit('key',' values');

而在接收DeviceEventEmitter的页面或者组件中使用,需要分为两步:

    componentDidMount() {
        //注意addListener的key和emit的key保持一致
        this.msgListener = DeviceEventEmitter.addListener('key',(values) => {
            //todo....
        });

    }

此处有炸弹,需要谨慎!!!!

假设有a b c 三个页面, a push> b push> c a发通知到c,此时c页面组件还未进行渲染。等渲染c时,c无法获取到a的通知,此时,c想要a的通知数据,只能正向传值。

DeviceEventEmitter只对同页面,或者页面内的子组件,或者页面内的子组件中的自组件有效,换句话说:只能针对已经加载的组件有。对于那些还未加载到的页面或者组件,使用addListener是无法获取到emit的值。最常见情况:在当前页面emit还未加载的页面进行数据变化,进入加载页面,addListener未生效。


当然,还可以使用Redux,Mobx来进行组件或者页面状态的修改,此处未提及,感兴趣的同学请自行百度。

上一篇 下一篇

猜你喜欢

热点阅读