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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342