快速上手React(中)

9 篇文章 0 订阅

0.箭头函数绑定this

//src/index.js
// 1.引入模块
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    // 方法一
    handelClick() {
        console.log(this);
    }
    // 方法二(推荐写法)
    // handelClick = () => {
    //     console.log(this);
    // }
    render() {
        // 方法一:包裹一层 箭头函数的方式 (不太推荐)
        return (<button onClick={() => this.handelClick()}>按钮</button>)
        // 方法二:类实例箭头函数的方式(推荐写法)
        // return (<button onClick={this.handelClick}>按钮</button>)
        // 方法三:调用的时候用bind绑定this (传参的时候使用)
        // return (<button onClick={this.handelClick.bind(this)}>按钮</button>)
    }
}

//3.将创建好的类组件挂载到dom上
ReactDOM.render(<App />, document.getElementById('root'))

1.call apply bind 区别和用法

  • 功能都是操作不同对象
  • apply需要用数组包裹参数
  • bind返回新函数需要自调用
<script>
        let obj = {
            name: '山竹',
            say(value, value2) {
                console.log(this.name, value, value2);
            }
        }
        let newName = { name: '杀生丸' }
        // call()
        obj.say.call(newName, '超级帅der')//杀生丸 超级帅der undefined
        // apply()
        obj.say.apply(newName, ['超级帅der'])//杀生丸 超级帅der undefined
        // bind()
        obj.say.bind(newName, '超级帅der')('只有bind才显示value2')//杀生丸 超级帅der 只有bind才显示value2
    </script>

2.受控表单实现

  1. 声明state
  2. 绑定state中的值 给表单
  3. 监听表单值改变 并且更新到state当中
//src/index.js
// 1.引入模块
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    // 声明state
    state = {
        isValue: '',
        ispwd: ''
    }
    // 2.监听触发事件,获取input事件
    handelChange = (e) => {
        // 结构name
        const { name } = e.target
        console.log(e);
        //获取的name更新给声明的state
        this.setState({
            [name]: e.target.value
        })
    }
    // 点击按钮
    handelClick = (e) => {
        console.log(e)
    }
    render() {
        return (
            <div>
                {/* 1.触发事件 3.接收到更新的state赋值给input中的value*/}
                <div>
                    账户名:
                <input onChange={this.handelChange} value={this.state.isValue}
                        type='text'
                        name='isValue'
                    />
                </div>
                <div>
                    密码:
                 <input onChange={this.handelChange} value={this.state.isPwd}
                        type='pwd'
                        name='ispwd'
                    />
                </div>
            </div>)
    }
}

//3.将创建好的类组件挂载到dom上
ReactDOM.render(<App />, document.getElementById('root'))

3.非受控表单实现

  1. 创建Ref引用
  2. 绑定Ref引用到表单元素
  3. 通过引用拿到具体的表单元素以及值
  4. defaultValue默认值设定
//src/index.js
// 1.引入模块
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
    //    1.创建Ref引用
    constructor() {
        super()
        //创建引用,引用命名一Ref结尾
        //React.createRef()是一个工厂设计模式
        this.usernameRef = React.createRef()
        this.pwdRef = React.createRef()
    }
    // 3.通过引用拿到具体的表单元素以及值
    handelClick = () => {
        console.log(this.usernameRef.current.value, this.pwdRef.current.value);
    }
    //设定state
    state = { username: '山竹' }
    render() {
        return (
            <div>
                {/* 2.绑定Ref引用到表单元素 */}
                {/* 4.defaultValue默认值设定 */}
                <div>
                    账户名:
                <input defaultValue={this.state.username} type='text' ref={this.usernameRef} />
                </div>
                <div>
                    密码:
                 <input type='pwd' ref={this.pwdRef} />
                </div>
                <button onClick={this.handelClick}>按钮</button>
            </div>)
    }
}

//3.将创建好的类组件挂载到dom上
ReactDOM.render(<App />, document.getElementById('root'))

4.表单总结

  1. 表单值处理推荐使用受控表单的模式,因为拿值比较方便
  2. 非受控表单主要用于需要操作DOM的时候,比如:video canvas 或者动画等待
  3. 受控表单最后拿值可以直接到state当中去拿,非受控拿值 需要通过引用挨个取值

5.组件传值父传子

this.props接收父组件传递的值

//src/index.js
// 1.引入模块
import React, { Component } from 'react'
import ReactDOM from 'react-dom'


class Father extends Component {
    state = {
        num: 18
    }
    render() {
        return (
            <div style={{ background: 'red' }}>
                我是父组件
                <Son num={this.state.num} />
                {/* 引入子组件 */}
            </div>
        )
    }
}

class Son extends Component {
    render() {
        return (
            // 通过this.props接收
            <div style={{ background: 'pink', margin: 10 }}>
                我是子组件,从父组件传递过来的值是{this.props.num}
            </div>
        )
    }
}

//3.将创建好的类组件挂载到dom上
ReactDOM.render(<Father />, document.getElementById('root'))

在这里插入图片描述

6.组建传值子传父

  1. 父组件定义一个方法
  2. 父组件在使用子组件的地方 通过组件传值 传方法给子组件
  3. 子组件拿到父组件传过来的方法 调用该方法同时传实参给方法
  4. 父组件方法中通过形参难道子组件传来的数据 更新到state当中
//src/index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class Father extends Component {
    state = {
        num: ''
    }
    // 4.监听子组件事件
    // 需要用箭头函数改变this指向,否则指向调用者--子组件
    receiveNum = (props) => {
        console.log(props);
        // 5.保存子组件的值
        this.setState({
            num: props
        })
    }
    render() {
        return (
            <div style={{ background: 'red' }}>
                我是父组件,从子组件传递过来的值是:{this.state.num}
                {/* 3.监听子组件传递过来的事件 */}
                <Son onReceive={this.receiveNum} />
            </div>
        )
    }
}

class Son extends Component {
    state = {
        num: 18
    }
    // 2.传递给父组件
    handelClick = () => {
        this.props.onReceive(this.state.num)
    }
    render() {
        return (
            <div style={{ background: 'pink', margin: 10 }}>
                我是子组件
                {/* 1.触发子传父事件 */}
                <button onClick={this.handelClick}>按钮</button>
            </div>
        )
    }
}

ReactDOM.render(<Father />, document.getElementById('root'))

在这里插入图片描述

7.兄弟传值

子传父再父传子

在这里插入图片描述

//src/index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class Father extends Component {
    state = {
        num: ''
    }
    // 4.监听子组件事件
    // 需要用箭头函数改变this指向,否则指向调用者--子组件
    receiveNum = (props) => {
        console.log(props);
        // 5.保存子组件的值
        this.setState({
            num: props
        })
    }
    render() {
        return (
            <div style={{ background: 'red' }}>
                我是父组件,从子组件传递过来的值是:{this.state.num}
                {/* 3.监听子组件传递过来的事件 */}
                {/* 第一个子组件 */}
                <Son onReceive={this.receiveNum} />
                {/* 第二个子组件 */}
                {/* 6.传递给第二个子组件,形成兄弟传值 */}
                <Sony num={this.state.num} />
            </div>
        )
    }
}

class Son extends Component {
    state = {
        num: 18
    }
    // 2.传递给父组件
    handelClick = () => {
        this.props.onReceive(this.state.num)
    }
    render() {
        return (
            <div style={{ background: 'pink', margin: 10 }}>
                我是子组件
                {/* 1.触发子传父事件 */}
                <button onClick={this.handelClick}>按钮</button>
            </div>
        )
    }
}

class Sony extends Component {
    render() {
        return (
            <div style={{ background: 'yellow', margin: 10 }}>
                {/* 7.接收父组件的值,形成兄弟传值 */}
                我是第二个子组件,从父组件接收的值是{this.props.num}
            </div>
        )
    }
}

ReactDOM.render(<Father />, document.getElementById('root'))

在这里插入图片描述

8.Context 跨组件层级传值

  1. 创建Provider和Consumer组件
  2. 使用Procider传递值
  3. 使用Consumer接收跨组件值
import React from 'react';
import ReactDOM from 'react-dom';

// 引入样式
import './index.css';

// 1.创建Provider和Consumer组件
const { Provider, Consumer } = React.createContext()

class App extends React.Component {
    state = {
        txt: '传家宝'
    }
    render() {
        return (
            // 2.使用Procider传递值
            <Provider value={this.state.txt}>
                <div className="app  container">
                    <Node />
                </div>
            </Provider>
        )
    }
}

const Node = props => {
    return (
        <div className="node">
            <SubNode />
        </div>
    )
}

const SubNode = props => {
    return (
        <div className="subnode">
            <Child />
        </div>
    )
}

const Child = props => {
    return (
        <div className="child">
            {/* 3.使用Consumer接收跨组件值 */}
            我是曾孙子节点 --
            <Consumer>
                {(data) => {
                    return data
                }}
            </Consumer>

        </div>
    )
}



ReactDOM.render(<App />, document.getElementById('root'));

在这里插入图片描述
样式参考

/* index.css */
.container {
    text-align: center;
    margin: 0 auto;
}


.btn {
    width: 200px;
    height: 100px;
    border-radius: 50px;
    background-color: aquamarine;
}

span {
    margin: 10px;
}



.app {
    width: 300px;
    padding: 10px;
    border: 1px solid #999;
}

.user {
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 10px;
}

.content {
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 10px;
}

.no-comment {
    text-align: center;
    margin-top: 30px;
}


.app {
    height: 100px;
    padding: 10px;
    background-color: #c4d0dc;
}

.node {
    height: 80px;
    padding: 10px;
    background-color: yellowgreen;
}

.subnode {
    height: 60px;
    padding: 10px;
    background-color: #dcdc39;
}

.child {
    height: 40px;
    padding: 10px;
    background-color: skyblue;
}

9.props之children的用法

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// 引入图片
import img from './image/5.jpg'
// 方法一:函数式
// class App extends Component {
//     render() {
//         return (
//             <div>
//                 {this.props.children()}
//             </div>
//         )
//     }
// }
// 方法二
class App extends Component {
    render() {
        return (
            <div>
                {this.props.children}
            </div>
        )
    }
}

//方法一
// ReactDOM.render(<App>{() => {
//     return <img src={img} />
// }}</App>, document.getElementById('root'));

// 方法二
ReactDOM.render(<App><img src={img} />
</App>, document.getElementById('root'));

效果
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值