React note8(脚手架:组件传值&跨组件传值context上下文对象&条件/循环渲染&ref)

组件传值


(一)正向传值—使用props

正向传值,父组件向子组件传值,通过props来传递。

但是注意:props的值是不能修改的,如果想修改的话,配合state使用,通过state来修改值。
在这里插入图片描述

props正向传值小栗子:

父组件在传值的时候有两种方式:
(1)直接在调用的子组件里面传值—直接传值;
(2)通过ES6扩展运算符给子组件传值—ES6扩展运算符传值。

子组件在接收父组件传过来的数据时也有两种方式:
(1)直接this.props.xxx
(2)解构赋值 let {demo1,demo2,demo3}=this.props 下面就能直接使用demo1变量名了 。

>>Father.jsx

import React, { Component } from 'react'
import Son from "./Son.jsx"
export default class home extends Component {
    render() {
        let obj={demo1:"111",demo2:"222",demo3:"333"}
        return (
            <div>
                <h3>I'm Father.</h3>
                -----直接传值-----
               <Son demo1="aaa" demo2="bbb" demo3="ccc"/>
               -----ES6扩展运算符传值-----
               <Son {...obj} />
            </div>
        )
    }
}
>>Son.jsx

import React, { Component } from 'react'
export default class home extends Component {
    render() {
        let {demo2,demo3}=this.props;
        return (
            <div> 
               <h4>I'm Son.</h4>
               {/* 第一种:直接this.props.xxx */}
               <p>{this.props.demo1}</p>

               {/* 第二种:解构赋值 let {demo1,demo2,demo3}=obj  下面就能直接使用了 */}
               <p>{demo2}</p>
               <p>{demo3}</p>
            </div>
        )
    }
}

在这里插入图片描述

(二)逆向传值—函数传值

通过事件调用函数传递。

在子组件中使用this.props.调用的函数名,绑定发送数据:
在这里插入图片描述

在父组件中进行函数传递:
在这里插入图片描述
在这里插入图片描述

事件函数逆向传值小栗子:
>>Father.jsx

import React, { Component } from 'react'
import Son from "./Son.jsx"
export default class home extends Component {
    fuFun=(text)=>{
        console.log(text)
    }
    render() {
        let obj={demo1:"111",demo2:"222",demo3:"333"}
        return (
            <div>
                <h3>I'm Father.</h3>
               子组件逆向传值   在父组件中传递过去一个函数 sonFun
               <Son sonFun={this.fuFun}/>
            </div>
        )
    }
}
>>Son.jsx

import React, { Component } from 'react'
export default class home extends Component {
    render() {
        let {demo2,demo3}=this.props;
        return (
            <div> 
               <h4>I'm Son.</h4>
            	子组件中正向接收一个函数 sonFun ,使用this.props.函数名.bind(this,"数据") ,绑定发送数据
            	<button onClick={this.props.sonFun.bind(this,"子传给父的数据")}>点击-逆向传值</button>
            </div>
        )
    }
}

在这里插入图片描述

(三)同级传值—pubsub-js

同级传值使用 pubsub-js。

下载:npm install --save pubsub-js

在第一个组件中进行数据抛出 PubSub.publish("事件名","数据")

在这里插入图片描述

在第二个组件中接收PubSub.subscribe("监听的事件",(事件,数据)=>{})

在这里插入图片描述

pubsub-js兄弟传值小栗子:

一个兄弟组件里面抛出一个事件 eventName :

>>Bro1.jsx

import React, { Component } from 'react'
import Pubsub from "pubsub-js"

export default class Bro1 extends Component {
    fun=()=>{
        				// 事件名      数据
        Pubsub.publish("eventName","Bro1发出的数据") 
    }
    render() {
        return (
            <div>
                <h4>I'm big bro1.</h4>

                {/* 通过一个事件触发 */}
                <button onClick={this.fun}>点击-向兄弟传递数据</button>
            </div>
        )
    }
}

第二兄弟组件里面监听这个事件,然后我是通过state将数据动态更新到页面上:

>>Bro2.jsx

import React, { Component } from 'react'
import Pubsub from "pubsub-js"

export default class Bro1 extends Component {
    constructor(props) {
        super(props)
        this.state = {
            texta: "empty",
            textb: "empty"
        }
    }
    // 在钩子里面接收兄弟传过来的数据  比如在组件创建完成后
    componentDidMount() {
        Pubsub.subscribe("eventName", (a, b) => {
            console.log("a:",a)
            console.log("b:",b)
            this.setState({
                texta: a,
                textb: b
            })
        })
    }
    render() {
        return (
            <div>
                <h4>I'm little bro2.</h4>
                <p>事件名:{this.state.texta} &emsp; 数据:{this.state.textb}</p>
            </div>
        )
    }
}

然后将这两个兄弟组件引入到父组件里面,再把父组件引入到根组件里面,就能查看效果啦。

>>Father.jsx

import React, { Component } from 'react'
import Bro1 from "./Bro1.jsx"
import Bro2 from "./Bro2.jsx"
export default class home extends Component {
    render() {
        return (
            <div>
                <h3>I'm Father.</h3>
               {/* 兄弟传值 */}
               <Bro1/>
               <Bro2/>
            </div>
        )
    }
}
 

在这里插入图片描述 在这里插入图片描述

跨组件传值context


react 组件间传递数据是通过 props 向下,单向传递的。从父级一层一层地通过 props 地向下传递到子子孙孙,有的时候我们组件一层一层的嵌套多层,这样这种方式一层一层传递麻烦,如果想跃层传递,这就会用到context

context:上下文对象。很好的解决了跨组件传值的复杂度,可以快速的进行跨组件数据的传递。

如果想要使用context进行跨组件传值,那么就要使用createContext()方法,同时方法中给我们提供了两个对象:

  • Provider对象      生产者---->用来生产数据
  • Consumer对象   消费者---->用来使用数据

注意: context 只能传 不能改

(一)context使用

在src下创建文件与文件夹,用来容纳context对象
在这里插入图片描述

创建内容并且引用createContext对象,然后通过this.props.children来进行子内容的调用。

在这里插入图片描述

根组件中使用。这里注意一下,原本包裹< App/> 的是react中的严格模式组件,不过我们把严格模式替换掉成了自定义context上下文对象组件了。
在这里插入图片描述
创建Provider生产者Consumer消费者对象,并且创建数据。
在这里插入图片描述

在需要的组件中进行使用,比如使用某个数据。
在这里插入图片描述
如果需要传递多个值,那么就传递一个对象。
在这里插入图片描述

(二)context在js中使用

导出context。

import React, { Component, createContext } from 'react'

let context = createContext()
let { Provider, Consumer } = context

class MyContext extends Component {
    render() {
        return (
            <div>
                <Provider value={{ name: "sky", age: 18 }}>{this.props.children}</Provider>
            </div>
        )
    }
}
export { MyContext, Consumer, context }

在需要使用的组件中引用使用。
在这里插入图片描述

(三)跨层级传值 小例子

在src下新建一个文件夹,用来存放context相关文件。
在这里插入图片描述

传递单个value。
>>index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {MyContext} from "./myContext/MyContext.js"

ReactDOM.render(
  <MyContext>
  {/* <React.StrictMode> */}
    <App />
  {/* </React.StrictMode>, */}
  </MyContext>,
  document.getElementById('root')
);

serviceWorker.unregister();

React.StrictMode是在react中开启严格模式,参考博文:https://www.jianshu.com/p/d100c6a86c75

>>MyContext.js

import React, { Component, createContext } from 'react'

let context = createContext()
let { Provider, Consumer } = context

class MyContext extends Component {
    render() {
        return (
            <div>
                {/* 上下文对象 --- 凌驾于所有组件之上--
                -把所有组件当成自己的子组件--
                使用this.props.children
                {this.props.children} */}

                {/* 生产者 传递单个值*/}
                {/* <Provider value={123}>{this.props.children}</Provider> */}
                
                {/* 传递多个只值,放在对象里 */}
                <Provider value={{ name: "sky", age: 18 }}>{this.props.children}</Provider>

                {/* 消费者 在需要用数据的地方使用消费者 
                <Consumer></Consumer> */}
            </div>
        )
    }
}
export { MyContext, Consumer, context }
``
然后在Bro1中使用
```js
>>Bro1.jsx

import React, { Component } from 'react'
import Pubsub from "pubsub-js"
import { Consumer } from "../myContext/MyContext.js"

export default class Bro1 extends Component {
    render() {
        return (
            <div>
                <h4>I'm big bro1.</h4>
                
                消费者消费数据
                <Consumer>
                    {
                        // value就是数据
                        (value) => {
                            return (
                                // 1、value为非对象类型的值,则获取方法如下
                                // <div>{value}</div>
                                
                                // 2、value为对象类型的值,则获取方法如下
                                // <div>{value.name}</div>
                                
                                // 3、还可以转化对象为数组,然后遍历出值
                                <p>{
                                    Object.values(value).map((item, index) => {
                                        return (
                                            <span key={index}>{item} </span>
                                        )
                                    })
                                }</p>
                            )
                        }
                    }
                </Consumer>
            </div>
        )
    }
}
传递多个数据------看上面
如何在js中使用context?
>>Bro1.jsx

//先引入
import { Consumer,context } from "../myContext/MyContext.js"
//然后在一个组件中先定义,再使用
static contextType=context
componentDidMount() {
    console.log("在js中使用context上下文对象:",this.context.name);
}

React脚手架中设置样式


其实跟本地模式没啥区别。

创建样式文件。
在这里插入图片描述
引入样式文件。
在这里插入图片描述

注意添加类使用的是className


条件渲染


跟本地模式也没啥区别。

创建按钮并且添加事件与函数:
在这里插入图片描述
在这里插入图片描述

使用三目判断是否显示:(第一次见还能直接这么写)
在这里插入图片描述

循环渲染


(一)根据数据动态生成

创建数据:
在这里插入图片描述

通过map遍历生成内容,注意要加key要不然会报错。
在这里插入图片描述
在这里插入图片描述

不过最好不要把index作为key值,因为当数组变化了,index也会变化,从而lastIndex和index不再能正确代表新旧index,应该用元素的一个唯一标识id作为key值。

react VS Vue diff算法:https://www.jianshu.com/p/a5a02511eb9a

不使用index作为key标识:https://blog.csdn.net/qq_43351249/article/details/102995481

(二)循环渲染—删除内容

父组件正向传递函数给子组件:
在这里插入图片描述

子组件再逆向传值给父组件要删除的内容:
在这里插入图片描述

父组件接收到值开始删除:
在这里插入图片描述

ref使用


在脚手架环境中使用createRef()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值