第一種:屬性傳遞方法(單向數(shù)據(jù)流的)
父親把屬性傳遞給兒子,或者是后代.(兒子是傳不了父親的),但是父親組件把自身的方法通過屬性傳遞給子組件,子組件不僅能接受這個方法,還能執(zhí)行這個方法.這樣就能達到子組件執(zhí)行方法的時候把一些屬性傳遞給父組件,并修改父組件中的一些信息.在react中屬性傳遞方法類似于Jsonp,類似于hybride H5和原生App 的交互方式中的場景,能實現(xiàn)子改父.但是這僅僅局限于父子關(guān)系.如果是爺孫關(guān)系,還得把屬性傳遞給兒子,再傳遞給孫子(如果關(guān)系層級更多,還得一層層的去傳遞,這樣寫起來比較麻煩).
第二種:發(fā)布訂閱的方式
應用第三方庫,或者是自己寫一個發(fā)布訂閱模式的代碼
第三種:執(zhí)行上下文
在組件元素當中,為了快速,方便的寫可以用react中context這個API,在祖先元素當中,我們首先用react.Createcontext創(chuàng)建一個context,在他的祖先元素當中通過執(zhí)行上下文中那個對象中的Provider組件,把后代元素要使用的上下文通過value的方式注冊下來,那么后代可以用Consumer或contextType來進行消費.
好處:執(zhí)行上下文有一個好處,只要他們有一個共同的祖先,都可以調(diào)用祖先上的信息),屬性的特點:只要是父子的,哪怕是兄弟,他倆只要有一個共同的爹,都是可以用屬性的方式.
缺點;執(zhí)行上下文雖然解決了兄弟組件之間的傳遞但是他的缺點是要把所有的信息都寫在祖先組件上,而且,我們想要信息改變的時候,要把祖先中某個方法放到上下文當中,由后代去執(zhí)行這個方法,執(zhí)行的方法還是祖先的方法,而祖先方法里邊通過修改狀態(tài)讓祖先重新渲染,才能保證后代元素重新渲染,所以祖先的業(yè)務(wù)邏輯隨著項目的不斷增大會越來越多,這樣也不是特別好.
import React from "react";
import PropTypes from "prop-types";
import "./Vote.css";
export default class Vote extends React.Component {
//設(shè)置屬性的規(guī)則
static defaultProps = {
supNum: 0,
oppNum: 0
}
static propTypes = {
title: PropTypes.string.isRequired,
supNum: PropTypes.number,
oppNum: PropTypes.number
}
//設(shè)置初始值
constructor(props) {
super(props)
this.state = {
//把傳進來的屬性復制給了狀態(tài),好處是 狀態(tài)可以在組件中修改沼瘫,屬性不能
supNum: this.props.supNum,
oppNum: this.props.oppNum
}
}
render() {
let { supNum, oppNum } = this.state;
return <div className="voteBox">
<header className="headerBox">
<h3>{this.props.title}</h3>
<span>N:{supNum + oppNum}</span>
</header>
<main>
<p>支持人數(shù):{supNum}</p>
<p>反對人數(shù):{oppNum}</p>
<p>支持率:{this.getRatio()}</p>
</main>
<footer className="footerBox">
<button onClick={this.handle.bind(this,"A")}>支持</button>
<button onClick={this.handle.bind(this,"B")}> 反對</button>
<button onClick={this.text}>測試ev</button>
</footer>
</div>
}
//=>定義一些需要使用的方法(vote.prototype) :vue中的寫法抬纸,方法中的this都是vue的實例,不管怎么調(diào)用都是這樣耿戚,但是react中不是湿故,他就是我們原生js中的特性,this是不固定的膜蛔,看你怎么調(diào)用來決定
//=>為了保證this是實例坛猪,我們寫的方法一般基于箭頭來構(gòu)建
getRatio=()=> {
// this是實例了
let {supNum,oppNum} = this.state,
ratio=null,
total =supNum+oppNum;
ratio =total===0? 0:supNum/total*100;
return ratio.toFixed(2)+"%";
}
handle=(type,ev)=>{
console.log(ev)
console.log(type)
let {supNum,oppNum} = this.state
if(type==="A"){
this.setState({
supNum:supNum+1
})
return ;
}else if(type==="B"){
this.setState({
oppNum:oppNum+1
})
return
}else{
return
}
}
// text(){
// console.log(this) //這么寫 this不是當前類的實例
// }
//一般用箭頭函數(shù)讓 this指向?qū)嵗? text=ev=>{
//=>ev不是我們原生js的事件對象(經(jīng)過react處理的,把每一個屬性都getter和setter了),但是用的時候和原生用法一致即可
// console.log(ev.currentTarget)
ev.persist();
console.log(ev)
//ev.currentTarget能知道當前元素 輸出 <button>測試ev</button>
console.log(ev.currentTarget)
}
}