react组件内部通信

react组件内部通信主要分为两部分:数据展示与事件处理


  • 数据的双向绑定

    首先来一个双向绑定来开开胃,react不像vue、angular一样都有双向绑定的自定义标签 v-model、 ng-model ,自定义标签方便了数据的双向绑定的写法;react中就没有这种自定义标签,需要用代码逻辑来实现

    class App extends Component {
     constructor(props) {
      super(props);
      this.state = {
       inputValue: "test",
      };
      this.changeInput = this.changeInput.bind(this);
     }
     
     changeInput(e) {
      // 将改变后的 input 值赋值给 inputValue,通过事件对象 $event.target.value 实现
      this.setState({
       inputValue: e.target.value
      });
     }
     
     render() {
      // input 改变时触发 changeInput
      return (
       <div className="App">
        <input value={this.state.inputValue} onChange={this.changeInput} />
        <p>{this.state.inputValue}</p>
       </div>
      );
     }
    }
    export default App;
  • 数据的展示

    组件内部的展示和更新都是通过 state 来实现的,如果要使用 state 必须使用 ES6 的 class 定义组件。数据更新在双向数据绑定部分探讨,这部分仅讨论展示初始化数据。

    如果你熟悉Vue、 React 的state对象相当于Vue的data对象

    下面是简单的数据展示

    class App extends Component {
     constructor(props) {
     super(props);
     
     // 初始化 state
     this.state = {
      inputValue: "test",
     };
     }
     
     render() {
     // 注意,在 react 中,DOM 元素是对象,所以使用‘()'包住 
     return (
      <div className="App">
      <p>{this.state.inputValue}</p>
      </div>
     );
     }
    }
    export default App;
    

      

    在通过 class 定义的 React 组件中,除了生命周期钩子函数, constructor() 和 render() 着两个方法也是自动执行的,先执行 constructor() ,执行 constructor() 的同时也是再为 render() 渲染 DOM 做数据准备。

    实际上 constructor() 函数是组件生命周期中调用的第一个函数

  • 父子组件之间的数据传递以及事件、方法

    首先创建两个组件父组件和子组件分别命名为 父---Sudoku、子---Popup。应用场景是父组件为任务组件,子组件为任务介绍以及所需完成任务功能。父组件任务逻辑比较复杂和业务逻辑需求特殊,所以将父组件Sudoku封装了起来,在页面组件PromoteProsperity 中使用下面有介绍里面应用到的react组件事件和方法的传递。

    import React, { Component } from 'react';
    import Popup from '../../components/Popup/index'
    class Sudoku extends Component{
        constructor(props){
            super(props);
            this.state = {
                checked : false, //显示隐藏提示组件
                isShowImg:false,//动态确定按钮的显示隐藏
                someConster:'',//任务的内容
                beginDate:'',//开始的时间
                endDate:'',//结束的时间
                code:'', // 任务标识
                inviteCode:'',//邀请码
                linkUrl:'',//去做任务的地址
            }
        }
        promoteClcik (n) {   // 点击任务,弹框的显示
            console.log(n)
            let signinBeginDate = n.beginDate;
            let signEndDate = n.endDate;
            let startCode = n.code;
            let conatenCon = n.explain;
            let isConImg  = n.isComplete;//任务的状态 
            let Name = n.name
            let url = n.url;
            let type = n.type
            if(type === 2){
                TDAPP.onEvent('QKH502002','特殊任务',{Name})//特殊任务的埋点
            }else if(type ===1){
                TDAPP.onEvent('QKH502001','日常任务',{Name})//日常任务的埋点
            }
            if(url !== undefined){ // 判断弹框内容以及需要的内容
                    this.setState({
                        someConster:conatenCon,
                        beginDate:signinBeginDate,
                        endDate:signEndDate,
                        code:startCode,
                        isShowImg:isConImg,
                        linkUrl:url
                    })
            }else{
                    this.setState({
                        someConster:conatenCon,
                        beginDate:signinBeginDate,
                        endDate:signEndDate,
                        code:startCode,
                        isShowImg:isConImg,
                    })
            }
           this.setState({
                checked:!this.state.checked
           })  
        }
        onokClick(code,win,url){ // 去完成,跳转页面做任务
            console.log(code,win,url);
                if(win){
                    this.setState({
                        checked:!this.state.checked
                    })
                    TDAPP.onEvent('QKH502004')
                }else{
                    let pushUrl = url.split('url相同的前缀进行截取');
                    if(pushUrl[1]){
                        this.props.history.push(pushUrl[1]);
                    }else{
                        jsbridge.downApp(url);
                    }
                    TDAPP.onEvent('QKH502003'); 
                }  
            }
           this.setState({
                checked:!this.state.checked
           })
        }
        getInviteCode(){
            getInviteInfo().then( res=>{
                if(res.success){
                    this.setState({
                        inviteCode:res.data.code
                    })
                }else{
                    this.layer(res.message);
                }
            })
            .catch( ()=>{
                this.layer('服务器开小差,请稍后再试');
            } )
        }
        propsmote(shareName){
            TaskComplete(shareName).then(res =>{
                if(res.success){
                  this.props.megShow()
                }else{
                    console.log(res.message);
                }
            }).catch(()=>{
                this.layer('服务器开小差,请稍后再试');
            })
        }
        disClick(){ // 隐藏任务弹出框
            this.setState({
                checked:!this.state.checked
               })
        }
        componentDidMount(){
            this.getInviteCode();
        }
        render(){
            const {beginDate,endDate,code,isShowImg,linkUrl} = this.state
          
            const {newtitle,sudoArr,text} = this.props;  //父组件传递的值
            return (
                <div>
                  <div className={style.promconter}>
                      <div className={style.contertitle} >
                      <img src={Blueox} alt=""/><div>{newtitle}</div>
                      {
                      sudoArr.map((item,index)=>{
                      return (
                      <div className={style.oneconter} key={index}>
                      <div onClick={()=>{this.promoteClcik(item)}}>
                      <img className={style.promfrider} src={item.picture} alt=""/>
                      <p>{item.name}</p>
                      <div className={style.probott}>
                          {
                          item.isComplete 
                          ? <div><img src={Finish}  alt=""/> <span>{text}</span></div>
                          :  <div><span >+{item.prosperityValue}</span> 繁荣值</div>
                           }                                                          
                </div>
               </div> 
                           {
                           // 任务弹框组件是否显示
                           this.state.checked 
                           ? <Popup beginDate={beginDate} //子组件的使用
                           endDate={endDate} 
                           contenter={this.state.someConster} 
                           title="任务说明" 
                           disClick={()=>{this.disClick()}}
                           onok={()=>{this.onokClick(code,isShowImg,linkUrl)}}
                           isShow={isShowImg}
                           code={code}
                           /> 
                           : ""
                           }                                              
                        </div>                                           
                        )   
                      })
                   }   
                  </div> 
                    
               </div>
                   
             </div>
            )
        }
    }
    ​
    ​
    export default Sudoku;

    在子组件Popup中使用父组件传递的参数和事件

    import React, { Component } from 'react';
    class Popup extends Component{
      constructor(props){
          super(props);
          this.state ={
          }
      }
      render(){
          const {disClick,onok,title,contenter,beginDate,endDate,isShow ,code} = this.props;
        return (
            <div>
              <div className={style.popup}>
                <div className={style.propfont}>
                      <div className={style.popobox}> {title} </div>//父组件中传递的title和时间
                      <div >{contenter}<span>任务有效期: {beginDate} 起至 {endDate}</span></div>
                      
                     {  
                       isShow
                       ?code === "share" || code ==="open_gome"
                       ? <img onClick={onok} src={BackBottom} alt=""/>//图片的展示
                       :<div className={style.popotext} onClick={onok}>确定</div>//事件的传递
                       : <img onClick={onok} src={BackBottom} alt=""/>
                     }
                </div>
              </div>
           </div> 
        )
      }
    }
    export default Popup;

    this.props接受父组件传递的数据和事件。

    其实父组件中有用到react方法传递 this.props.megShow()这是页面组件PromoteProsperity 传过来的,现在我们来看下页面组件里面是怎么样传的。

    import React, { Component } from 'react'
    import { TaskList } from './../../api/task'
    import Sudoku from '../../components/Sudoku/index'
    import Header from "Header"
    import Main from "Main"
    ​
    class PromoteProsperity extends Component {
        constructor(props){
            super(props);
            this.state ={
                typeOutProArr:[],
                typeTwoProArr:[],
                errorMesage:''
            }
        }
        megShow(){
            TaskList().then( res =>{
                if(res.success){
                    this.setState({
                        typeOutProArr:res.data.filter(item => item.type === 1),
                        typeTwoProArr:res.data.filter(item => item.type === 2),
                    });
                }else{
                    this.layer(res.message);
                }
            }).catch(() =>{
                this.layer('服务器开小差了,请稍后再试');
            })
        }
        componentDidMount(){
           this.megShow();
        } 
        
        render() {
            
            return (
                <div className="full"> 
                    <Header {...this.props} title="任务记录"/>
                    <Main {...this.props} hasHeader>
                        <div style={promotebackgStyle}>
                            <img style={promoStyle}  src={Bannar} alt=""/>
                            <Sudoku text="已完成" newtitle='日常任务' megShow={this.megShow.bind(this)}  sudoArr={this.state.typeOutProArr}></Sudoku>
                            <Sudoku  text="已完成" newtitle='特殊任务' megShow={this.megShow.bind(this)} sudoArr={this.state.typeTwoProArr} ></Sudoku>
                            <div style={footitleStyle}  >更多任务,敬请期待! </div>
                        </div>
                    </Main>
                </div>
                        
            );
        }
    }
    ​
    export default PromoteProsperity;

    如上所示,页面组件中使用了Sudoku组件将megShow方法传递下去 到应用组件中this.props.megShow()调用。

猜你喜欢

转载自www.cnblogs.com/eggplants/p/9584221.html