DvaJS快速上手(3)

前提:DvaJS快速上手(2)

簡單demo

完成頁面如上,父組件的state通過監聽props實現同步,所以父組件的state和props是同步的,加一組件的state也監聽props,所以當props發生變化時,加一組件的state也會發生變換化,但是加一按鈕的觸發事件是改變加一組件的state,而並沒有改變props,所以會出現加一state增加而父組件state不增加(沒有改變props所以父組件沒有監聽到);而減一按鈕的觸發事件爲改變props,所以會導致所有通過監聽props實現同步的state都發生變化,三個值都監聽props。(具體邏輯看下面動圖)

 

頁面運行情況

點擊加一按鈕,只有加一組件的state會發生變化

點擊減一按鈕,所有數值發生變化

 

代碼解析:

1、model(也就是存放同步props的地方)


export default {

  namespace: 'example',  //包名

  state: {
    number: 0, //用於同步的props
  },

  effects: {
    *fetch({ payload }, { call, put }) {  // eslint-disable-line
      yield put({ type: 'save' });
    },
  },

  reducers: {
    add(state, action) {
      return { ...state, number: action.payload };
      //詳情看擴展預算符
      //簡單理解就是將傳入的number賦值給當前props的number變量,實現更新數據
      //此處會導致number發生更新,也就是props發生了變化,所以有監聽props的組件也會發生變化
    },
  },

};

2、indexPage(也就是初始頁面)

import React, { Component } from 'react';
import { connect } from 'dva';
import styles from './IndexPage.css';
// 導入兩個組件
import AddOne from '../components/AddOne';
import MinusOne from '../components/MinusOne';

class IndexPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0,  // 組件的state,這裏新建一個number變量
      txtAdd: '加一',// 傳入子組件的數據,按鈕上的文字
      txtMinus: '減一',
    };
  }

  // react的生命週期,這個週期的作用是監聽props的變化
  // 這裏監聽的是props中的number變量
  UNSAFE_componentWillReceiveProps(nextProps) {
    // 監聽到props發生變化後便將值和當前的state同步
    this.setState({
      number: nextProps.example.number, // 這裏的exmaple是props的包名
    });
  }

  render() {
    return (
      <div className={styles.normal} >
        {/* 當前頁面的state */}
        <h1>父組件state: {this.state.number}</h1>
        {/* props */}
        <h1>父組件props: {this.props.example.number}</h1>
        <div>
          {/* 父組件可以通過下面這種形式將數據傳入子組件 */}
          <AddOne txtAdd={this.state.txtAdd} />
          <MinusOne txtMinus={this.state.txtMinus} />
        </div>
      </div>
    );
  }
}

// 連接example Model
export default connect(({ example }) => {
  return {
    example,
  };
},
)(IndexPage);

3、減一組件

import React, { Component } from 'react';
import { connect } from 'dva';

class MinusOne extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    //方法需要進行綁定
    this.btnMinus = this.btnMinus.bind(this);
  }

  // 減一方法按鈕
  btnMinus() {
    // 通過dispatch方法可以將數據發送到model中
    // type的格式爲 ‘包名/reducenr名’
    // payload用於傳送數據
    // 即這個方法的作用是將相關數據傳送到相關的reducer裏進行數據更新
    this.props.dispatch({
      type: 'example/add',
      payload: this.props.example.number - 1,
    });
  }

  render() {
    return (
      <div>
        <button
          style={{
            margin: '50px',
          }}
          onClick={this.btnMinus}
        >{this.props.txtMinus}</button>
      </div>
    );
  }
}

export default connect(({ example }) => {
  return {
    example,
  };
},
)(MinusOne);

加一組件

import React, { Component } from 'react';
import { connect } from 'dva';

class AddOne extends Component {
  constructor(props) {
    super(props);
    this.state = {
      number: 0,  // 組件的state,這裏新建一個number變量
    };
    //方法需要進行綁定
    this.btnAdd = this.btnAdd.bind(this);
  }

  // react的生命週期,這個週期的作用是監聽props的變化
  // 這裏監聽的是props中的number變量
  // 當減一按鈕觸發時候props發生了更新,這個方法就會監聽到,同時更新頁面的state
  UNSAFE_componentWillReceiveProps(nextProps) {
    this.setState({
      number: nextProps.example.number, // 這裏的exmaple是props的包名
    });
  }

  // 加一按鈕的方法,在這裏可以進行邏輯運算
  btnAdd() {
    // state只能通過setstate進行改變,這裏是將state中nunber變量進行+1
    // 區別於減一按鈕,此處並沒有用dipatch方法發送給model
    // 所以只有當前組件內的state進行了增加
    this.setState({
      number: this.state.number + 1,
    })
  }

  render() {
    return (
      <div>
        {/* 加一組件的state */}
        <div>加一組件:{this.state.number}</div>
        <button
          style={{
            margin: '50px',
          }}
          onClick={this.btnAdd}
          // 用父組件傳入的數據表示按鈕上的文字
        >{this.props.txtAdd}</button>
      </div>
    );
  }
}

export default connect(({ example }) => {
  return {
    example,
  };
},
)(AddOne);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章