1. 程式人生 > 實用技巧 >egg 跨域解決

egg 跨域解決

前言

這篇文章將還是通過例項的方式記錄一下react中元件之間的通訊方式,在react中,需要元件通訊的情況一般有以下幾種:

  • 父元件向子元件通訊
  • 子元件向父元件通訊
  • 跨級元件通訊
  • 非巢狀元件通訊

父元件向子元件通訊

React中採用資料單向流動的方式,父元件向子元件傳遞資料也是很常見的情況,父元件通過props向子元件傳遞資料

// 父元件
class App extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <Child name='tadpole' />
        )
    }
}

// 子元件
function Child(props) {
    return (
        <div
>{props.name}</div> ) }

子元件向父元件通訊

利用自定義事件,觸發回撥

// 父元件
class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {data: ''}
    }
    // 自定義的回撥事件
    childValue = data => {
        this.setState({data})
    }
    render() {
        return (
            <div>
                子元件傳遞過來的值:{this.state.data}
                <Child transferValue={this.childValue}/>
            </div>
        )
    }
}

// 子元件
class Child extends React.Component {
    constructor(props) {
        super(props)
        this.state = {data: ''}
    }
    valueChange = data => {
        // 保證子元件中的值和傳遞過去的值一致
        this.setState({
            data: data.target.value
        })
        // 觸發回撥 傳遞給父元件
        this.props.transferValue(data.target.value)
    }
    render() {
        return (
            <div>
                子元件: <input vlaue={this.state.data} onChange={this.valueChange} />
            </div>
        )
    }
}

跨級元件通訊

  • 一層一層傳遞props
  • Context

React中遵循資料單向流動(自上而下)的規則,其實我們完全可以通過每級元件傳遞props的方式來實現跨級通訊的目的。但是,在這個過程中,有些元件是不需要使用上級傳遞過來的props的,這種操作無疑是顯得多餘的,這個時候就引入了Context

Context提供了一個無需為每層元件手動新增props,就能在元件樹間進行資料傳遞的方法,它設計目的就是為了共享那些對於一個元件樹而言是“全域性”的資料
// 建立一個Context物件
const InitContext = React.createContext()

class App extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            // 使用一個 Provider 來將當前的 context 傳遞給以下的元件樹
            <InitContext.Provider value='tadpole'>
                <Child />
            </InitContext.Provider>
        )
    }
}

function Child(props) {
    return (
            <LastComponent />
        )
}

class LastComponent extends React.Component {
    // 指定 contextType 讀取當前的  context
    static contextType = InitContext
    render() {
        return (
            <div>name: {this.context}</div>
        )
    }
}

使用Context的注意點:

  • 每個Context物件都會返回一個Provider React元件
  • 只有當元件所處的樹中沒有匹配到Provider時,其defaultValue引數才會生效,預設值為undefined
  • 多個Provider也可以巢狀使用,裡層的會覆蓋外層的資料Provider接收一個value屬性,傳遞給消費元件(React會往上找到最近的Provider,然後使用它的值)
  • 可以在任何生命週期中訪問到,包括render函式中

更多參考Context API

廣州品牌設計公司https://www.houdianzi.com PPT模板下載大全https://redbox.wode007.com

非巢狀元件通訊

非巢狀元件通訊的思路一般有以下幾種:

  • 找到元件共同的父元件 (可以參考這個評論元件既有父子元件通訊也有兄弟元件通訊)
  • 利用Context API進行通訊,建立一個全域性可訪問的值
  • 利用events建立自定義事件

一般情況下,第一種方式找到共同的父元件可能存在很多級的情況,不是很友好,第二種方式對於後期維護或者說對於元件的可複用性不是很友好,所以,我們試一下自定義事件這種方式

首先,我們需要一個events這個包

npminstallevents-S

通過註冊、觸發事件來實現元件通訊

import { EventEmitter } from 'events'

const emitter = new EventEmitter()

// 元件A
class ComponentA extends React.Component {
    constructor(props) {
        super(props)
        this.state = {msg: ''}
    }
    componentDidMount() {
        // 元件掛載完畢的時候註冊事件
        this.eventEmitter = emitter.addListener('outputValue', msg => {
            this.setState({msg})
        })
    }
    componentWillUnMount() {
        // 元件銷燬之前移除事件
        emitter.removeListener(this.eventEmitter)
    }
    render() {
        return (
            <div>
                這是元件A
                <div>元件B傳遞過來的資料:{ this.state.msg }</div>
            </div>
        )
    }
}

// 元件B
class ComponentB extends React.Component {
    constructor(props) {
        super(props)
        this.state = {value: ''}
    }
    valueChange = data => {
        this.setState({
            value: data.target.value
        })
    }
    btnClick = () => {
        // 觸發自定義事件
        emitter.emit('outputValue', this.state.value)
    }
    render() {
        return (
            <div>
                這是元件B
                <input value={this.state.value} onChange={this.valueChange}></input>
                <button onClick={this.btnClick}>點選我傳遞資訊</button>
            </div>
            
        )
    }
}