react 父子組件傳值——父傳子

有興趣的小伙伴可以加Q群 879108483 互相學習

1.使用props傳值

具體實現

import React, { Component } from 'react';

/**父組件 */
export default class Parent extends Component {
    state = {
        msg: 1
    }
    render() {
        return (
            <div onClick={() => this.setState({ msg: this.state.msg + 1 })} >
                {/* 子組件 */}
                <Child msg={"傳遞給子組件的消息:" + this.state.msg.toString()} />
            </div>
        );
    }
}

/**子組件 */
class Child extends Component {
    // 默認的props 可寫可不寫
    static defaultProps = {
        msg: 1
    }
    render() {
        return (
            <div>
                {/* 通過props傳遞過來的參數 */}
                {this.props.msg}
            </div>
        )
    }
}

2.使用context (上下文)

Context被歸類為高級部分(Advanced),屬于React的高級API,但官方并不建議在穩定版的App中使用Context。實際上很多優秀的組件都是通過context來實現的,比如antd的主題樣式。用好context可以使項目更靈活。
Context 不僅僅適用于父傳子,還可以用來作為跨級傳遞數據,比如父組件傳孫子組件。如果要使用props達到這個效果就要層層傳遞props。 下面看看context實現方式

  1. 簡單使用 (老方法)
import React, { Component } from 'react';
import PropTypes from 'prop-types';

/**父組件 */
export default class Parent extends Component {
    state = {
        msg: 0
    }
    // 聲明Context屬性
    static childContextTypes = {
        // 數字類型
        msg: PropTypes.number,
        // 方法
        method: PropTypes.func
    }

    // 返回Context對象,約定好方法
    getChildContext() {
        return {
            msg: this.state.msg,
            method: () => "返回來的信息"
        }
    }
    render() {
        return (
            <div onClick={() => this.setState({ msg: this.state.msg + 1 })} >
                {/* 子組件 */}
                <Child />

                {/* 無狀態子組件 */}
                <ChildStateLess />
            </div>
        );
    }
}

/**子組件 */
class Child extends Component {
    // 聲明需要使用的Context屬性 必寫 不然聽過this.context.xxx 取出來的值為undefind
    static contextTypes = {
        msg: PropTypes.number
    }
    render() {
        return (
            <div>
                {/* 通過props傳遞過來的參數 */}
                {this.context.msg}
                {/* 孫子組件 */}
                <GrandsonComponent />
            </div>
        )
    }
}


/**無狀態組件 */
const ChildStateLess = (props, context) => {
    return (
        <div style={{ color: "red" }} >
            {context.msg}
        </div>

    )
}
/**為無狀態組件聲明需要使用的Context屬性 */
ChildStateLess.contextTypes = {
    msg: PropTypes.number
}

/**孫子組件 */
class GrandsonComponent extends Component {
    // 聲明需要使用的Context屬性 必寫 不然聽過this.context.xxx 取出來的值為undefind
    static contextTypes = {
        msg: PropTypes.number
    }
    render() {
        return (
            <div style={{ color: "green" }} >
                {/* 通過props傳遞過來的參數 */}
                {this.context.msg}
            </div>
        )
    }
}
  1. 使用<React. createContext> Api創建
import React from 'react';

const ExampleContext = React.createContext({
    msg: 0,
    method: () => "method"
});

此ExampleContext通過React.createContext創建,這個Context對象包含兩個組件,<Provider />和<Consumer />。
兩個API代替了getChildContext、childContextTypes、contextTypes這些繁瑣的api,更符合react的設計理念。

import React, { Component } from 'react';
import PropTypes from 'prop-types';

const ExampleContext = React.createContext('ExampleContext');


class ExampleProvider extends Component {
    state = {
        msg: 0
    }
    render() {
        return (
            <div onClick={() => {
                this.setState({ msg: this.state.msg + 1 })
            }} >
                <ExampleContext.Provider value={{ msg: this.state.msg, method: () => { } }} >
                    <Child />
                    <ChildStateLess />
                </ExampleContext.Provider>
            </div>
        );
    }
}

/**子組件 */
class Child extends Component {
    render() {
        return (
            <ExampleContext.Consumer>
                {
                    (context) => (
                        <div>
                            {/* 通過props傳遞過來的參數 */}
                            {context.msg}
                            {/* 孫子組件 */}
                            <GrandsonComponent />
                        </div>
                    )
                }
            </ExampleContext.Consumer>
        )
    }
}

/**無狀態組件 */
const ChildStateLess = (props, context) => {
    return (
        <ExampleContext.Consumer>
            {
                (context) => (
                    <div style={{ color: "green" }} >
                        {/* 通過props傳遞過來的參數 */}
                        {context.msg}
                        {/* 孫子組件 */}
                    </div>
                )
            }
        </ExampleContext.Consumer>
    )
}
/**為無狀態組件聲明需要使用的Context屬性 */
ChildStateLess.contextTypes = {
    msg: PropTypes.number
}

/**孫子組件 */
class GrandsonComponent extends Component {
    render() {
        return (
            <ExampleContext.Consumer>
                {
                    (context) => (
                        <div style={{ color: "red" }} >
                            {/* 通過props傳遞過來的參數 */}
                            {context.msg}
                            {/* 孫子組件 */}
                        </div>
                    )
                }
            </ExampleContext.Consumer>
        )
    }
}


export default ExampleProvider;
  1. 直接使用context的地方
    生命周期:
    1.componentWillReceiveProps(nextProps, nextContext)
    2.shouldComponentUpdate(nextProps, nextState, nextContext)
    3.componetWillUpdate(nextProps, nextState, nextContext)

構造函數: constructor(props, context)

web前端、react交流群:879108483

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。