React中组件通信01——props

React中组件通信01——props

  • 1. 父传子——props
    • 1.1 简单例子——props
    • 1.2 props 可以传递任何数据
      • 1.2.1 传递数字、对象等
      • 1.2.2 传递函数
      • 1.2.3 传递模版jsx
  • 2. 子传父 + 子传子——props
    • 2.1 父传子——传递函数
    • 2.2 子传父——通过父传子的函数实现
    • 2.3 优化 + 子传子(兄弟通信)
  • 3. render props
    • 3.1 组件标签上的标签体内容 传递
    • 3.2 render props
  • 4. 附代码:

1. 父传子——props

1.1 简单例子——props

  • 给子组件标签添加属性,属性名自定义,保持语义化即可。
  • 简单例子的核心代码,很简单就先截图吧,代码一起附在最后了,需要注意的是:类式组件与函数式组件的不同,如下:
    React中组件通信01——props_第1张图片
    React中组件通信01——props_第2张图片
    React中组件通信01——props_第3张图片

1.2 props 可以传递任何数据

1.2.1 传递数字、对象等

  • 上面我们看到传递的是字符串,下面简单看看传递对象,如下:
    React中组件通信01——props_第4张图片
    React中组件通信01——props_第5张图片
    React中组件通信01——props_第6张图片

1.2.2 传递函数

  • 这个详细看下面的 《2. 子传父 + 子传子》,下面有详细的介绍。

1.2.3 传递模版jsx

  • 如下:
    React中组件通信01——props_第7张图片
    React中组件通信01——props_第8张图片

2. 子传父 + 子传子——props

2.1 父传子——传递函数

  • 父传子函数的重要性,主要是下面怎么通过它实现子传父,简单看看父传子传函数,如下:
    React中组件通信01——props_第9张图片
  • 效果如下:
    React中组件通信01——props_第10张图片

2.2 子传父——通过父传子的函数实现

  • 下面需求是在,子组件里添加狗狗数据,并把数据传递给父组件,如下:
    React中组件通信01——props_第11张图片
  • 看效果:
    React中组件通信01——props_第12张图片

2.3 优化 + 子传子(兄弟通信)

  • 下面实现的需求是:在上面子组件D中有一个按钮,点击触发addDog(即:添加新的dog),并在另一个子组件E中有所体现。
  • 所以流程就是:父把函数addDog 传递给子组件D,子组件D中在调函数的时候把新增数据传给父,父的addDog中实现更新state数据,然后子组件E中实时展示最新的父中的传来的state数据,具体实现,如下:
    • parent.jx,如下:
      React中组件通信01——props_第13张图片
    • D组件如下:
      React中组件通信01——props_第14张图片
    • E组件中就简单了,直接接受父传来的数据即可,如下:
      React中组件通信01——props_第15张图片
  • 效果如下:
    React中组件通信01——props_第16张图片

3. render props

3.1 组件标签上的标签体内容 传递

  • 如果要传递组件标签上的标签体内容,获取的时候需要注意,此传递的内容放到了props的children属性上,如下:
    React中组件通信01——props_第17张图片
    React中组件通信01——props_第18张图片
  • 如果上面的标签体内容放的不是love,而是另外一个组件F,和ChildE形成父子关系的F组件,那依然是放在了props的children属性上,如下:
    React中组件通信01——props_第19张图片
    React中组件通信01——props_第20张图片

3.2 render props

  • 上面3.1中通过把组件F放在ChildE的标签体内来形成父子关系,可以用另外一种方式实现,就是通过传递箭头函数的方式,如下:
    React中组件通信01——props_第21张图片
    React中组件通信01——props_第22张图片
     <div className="childE">
         <ChildE dogList={this.state.dogList} 
                 testJsx={<p>测试一下传递jsx</p>}
                 render={()=><F/>}
                 />
     </div>
    
    {props.render()}
    
  • 传参数的情况,这里的函数名习惯用render,所以叫 render props ,如下:
    React中组件通信01——props_第23张图片
     <div className="childE">
         <ChildE dogList={this.state.dogList} 
                 testJsx={<p>测试一下传递jsx</p>}
                 // render={()=>}
                 render={(kind)=><F petKind={kind}/>}
                 />
     </div>
    
    {props.render('狗狗')}
    
    接到E传来的宠物类型是:{props.petKind}
    

4. 附代码:

  • parent.jsx:
    import React from "react";
    import ChildA from "./ChildA";
    import ChildB from "./ChildB";
    import ChildC from "./ChildC";
    import ChildD from "./ChildD";
    import ChildE from "./ChildE";
    import F from "./F";
    import './index.css'
    
    class Parent extends React.Component{
        state = {
            notice:'通知——今天有学生被开除了!',
            expelledNum:1,
            student:{name:'张三',age:21,reason:'逃课次数过多'},
            citys:['北京','上海','广州','深圳'],
            dogList:[
                {dogName:'麦兜',dogAge:3},
                {dogName:'贝塔',dogAge:2},
            ]
        }
        //给子组件传递的函数
        getCityStrs =()=>{
            // console.log(this.state.citys);
            return this.state.citys;
        }
        //给子组件传递的带参数函数,参数用来接受子组件在调用函数时给父组件传递的数据
        addDog =(dog)=>{
            console.log('收到子组件添加的新dog:',dog);
    
            //更新 state中 dogList的数据,这样子组件E中展示的数据就是最新的
            const dogList = this.state.dogList; //获取旧数据
    
            const newDogList = [...dogList,dog]; 
            console.log(newDogList);
            this.setState({dogList:newDogList});// 更新state
        }
    
        render(){
            return(
                <div className="parent">
                    我是父组件!
                    <div className="childA">
                        <ChildA notice={'通知——今天放假!'}/>
                    </div>
                    <div className="childB">
                        <ChildB notice={this.state.notice} expelledNum={this.state.expelledNum} student={this.state.student}/>
                    </div>
                    <div className="childC">
                        <ChildC getCityStrs={this.getCityStrs}/>
                    </div>
                    <div className="childD">
                        <ChildD addDog={this.addDog}/>
                    </div>
    
                    <div className="childE">
                        <ChildE dogList={this.state.dogList} 
                                testJsx={<p>测试一下传递jsx</p>}
                                // render={()=>}
                                render={(kind)=><F petKind={kind}/>}
                                />
                    </div>
                </div>
            )
        }
    }
    
    export default Parent;
    
  • xxxA.jsx
    import React from "react";
    
    class ChildA extends React.Component{
        render(){
            return(
                <div>
                    我是子组件A!!!——类式组件
                    <br /><br />
                    收到来自于父组件的数据:{this.props.notice}
                </div>
            )
        }
    }
    
    export default ChildA;
    
  • xxxB.jsx
    function ChildB(props){
        // console.log(props);
        const {name,age,reason} = props.student;
    
        return(
            <div>
                我是子组件B!!!——函数组件
    
                <br /><br />
                收到来自于父组件的数据:{props.notice}
                <br />
                被开除的人数是:{props.expelledNum}
                <br />
                被开除学生的信息:{name}-{age}-{reason}
    
            </div>
        )
    }
    
    export default ChildB;
    
  • xxxC.jsx
    function ChildC(props){
        // console.log(props);
    
        //调用父传过来的函数 获取citys数据
        const citys = props.getCityStrs();
        // console.log(citys);
    
        return(
            <div>
                我是子组件C!!!——函数组件
    
                <br /><br />
                收到父传子的函数,并调用函数获取了数据:
                {
                    citys.map((city,index)=>{
                        return <li key={index}>{city}</li>
                    })
                }
    
            </div>
        )
    }
    
    export default ChildC;
    
  • xxxD.jsx
    function ChildD(props){
        // console.log(props);
    
        const newDog = {dogName:'泡泡',dogAge:7};// 1. 准备要新增的dog数据
    
        const addDog = props.addDog;//2. 获取父组件传递过来的函数 addDog
        // addDog(newDog); //3. 在子组件中 执行 addDog 函数,并将新增dog传参过去给父组件
    
        return(
            <div>
                我是子组件D!!!——函数组件
    
                <br />
                {/* 1. 点击时,再把newDog 传过去   
                    2. 当然,这里如果看着不舒服,也可以把上面3步封装成一个函数,点击时触发新封装的函数 */}
                <button onClick={()=>addDog(newDog)}>添加狗狗</button>
            </div>
        )
    }
    
    export default ChildD;
    
  • xxxE.jsx
    function ChildE(props){
        console.log(props);
        const dogList = props.dogList;
        // console.log(dogList);
    
        return(
            <div>
                我是子组件E!!!——函数组件
                <br />
                {props.testJsx}
                <br />
    
                展示狗狗信息:
                <ul>
                    {dogList.map((dog,index)=><li key={index}>{dog.dogName}-{dog.dogAge}</li>)}
                </ul>
    
                <hr />
                {/* {props.children} */}
                {/* {props.render()} */}
                {props.render('狗狗')}
    
            </div>
        )
    }
    
    export default ChildE;
    
  • F.jsx
    function F(props){
    
        return(
            <div>
                我是E组件的子组件,我是F!!!——函数组件
                <br />
                接到E传来的宠物类型是:{props.petKind}
            </div>
        )
    }
    
    export default F;
    

你可能感兴趣的:(react,react.js,前端,前端框架)