react父子、子父、兄弟通訊

大熊睡不醒發表於2020-10-06

父子通訊

  1. 父元件定義一個狀態資料
  2. 呼叫子元件的時候,將資料通過屬性的方式傳給子元件
  3. 子元件通過this.props的方式接收
  4. 但是不能對傳遞過來的屬性進行修改

父元件

export default class Todos extends Component {
    state = {
        list:["a","b","c"]
    }
    render() {
        let {list} = this.state;
        return (
            <div>
                <List list={list}/>
            </div>
        )
    }
}

子元件

export default class List extends Component {
    render() {
        let {list} = this.props;
        return (
            <ul>
                {
                    list.map((item,index)=>{
                    return <li key={index}>{item}</li> 
                    })
                }
            </ul>
        )
    }
}

子父通訊

  1. 父元件需要定義一個狀態
  2. 父元件需要定義一個修改自身狀態的方法
  3. 在呼叫子元件的時候通過屬性將方法傳給子元件
  4. 子元件通過this.props.xxx觸發父元件的修改狀態的方法

父元件

export default class Todos extends Component {
    state = {
        list:["a","b","c"],
    }

    add = value =>{
        this.setState({
            list:[...this.state.list,value]
        })
    }

    render() {
        let {list} = this.state;
        return (
            <div>
                <Input add={this.add}/>
                <List list={list}/>
            </div>
        )
    }
}

子元件

export default class Input extends Component {

    handleKeyUp = e => {
        if(e.keyCode === 13){
            this.props.add(e.target.value)
            e.target.value = ""
        }
    }

    render() {
        return (
            <input onKeyUp={this.handleKeyUp}/>
        )
    }
}

兄弟元件

  1. 通過EventHub的機制.on繫結事件,通過trigger進行事件觸發
  2. 在兄弟一元件中建立更改自身狀態的方法
  3. 在componentDidMunt鉤子函式中通過EventHub.on(‘繫結第事件’,觸發的方法)監聽繫結事件
  4. 在兄弟二組建中通過EventHub.trigger(“觸發的繫結事件”,兄弟一更改狀態方法的形參)觸發繫結事件(訂閱過程)
  5. 【注】兄弟事件都需要引入event_hub.js檔案

兄元件

export default class One extends Component {
    state = {
        color:"red"
    }

    setColor = (color)=>{
        this.setState({
            color
        })
    }

    componentDidMount(){
        //需要監聽事件
        EventHub.on("change",this.setColor)
    }


    render() {
        return (
            <div>
                <p style={{background:this.state.color}}>One</p>
            </div>
        )
    }
}

弟元件

export default class Two extends Component {

    randomHexColor() { //隨機生成十六進位制顏色
        return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
    }

    changeColor = ()=>{
        //需要讓One元件的change事件進行觸發(訂閱過程)
        EventHub.trigger("change",this.randomHexColor())
    }
    render() {
        return (
            <div>
                Two -- <button onClick={this.changeColor}>點選變色</button>
            </div>
        )
    }
}

加粗樣式event_hub.js檔案

let callbackLists = {}
let eventHub = {
    trigger(eventName, data) {
        let callbackList = callbackLists[eventName]
        if (!callbackList) {
            return
        }
        for (let i = 0; i < callbackList.length; i++) {
            callbackList[i](data)
        }
    },
    on(eventName, callback) {
        if (!callbackLists[eventName]) {
            callbackLists[eventName] = [] // {change:[callback,callback2]}
        }
        callbackLists[eventName].push(callback)
    }
}

export default eventHub

相關文章