react基础部分2相关代码(帮助理解)

55 阅读3分钟

组件性能优化

PureComponent

import React from "react"
class Home extends React.PureComponent {
    constructor () {
        super()
        this.state = { age: 18 }
    }
    // shouldComponentUpdate(nextProps, nextState, nextContext) {
    //     if (this.state.age !== nextState.age) {
    //         return true
    //     }
    //     return false
    // }
    render() {
        console.log('Home-render')
        return (
            <div>
                Home
            </div>
        )
    }
}
class App extends React.Component {
    constructor () {
        super()
        this.state = {
            num: 0
        }
    }
    render() {
        console.log('App-render')
        return (
            <div>
                <Home />
                <div>{this.state.num}</div>
                <button onClick={() => this.showHome()}>App按钮</button>
            </div>
        )
    }
    showHome() {
        this.setState({
            num: this.state.num + 1
        })
    }
}
export default App

state注意点

永远不要直接修改state中的数据,如果要修改state中的数据,必须通过setState传递一个新的值

image.png

直接报问题,并且点击修改没有任何反应

  • 以前的版本
    • 可以改,但是在shouldComponentUpdate、React.PurComponent下不会触发更新
import React from 'react';
/*
1.state注意点
永远不要直接修改state中的数据
如果要修改state中的数据, 必须通过setState传递一个新的值
 */
class App extends React.PureComponent{
    constructor(props){
        super(props);
        this.state = {
            age : 0
        }
    }
    render(){
        console.log('App-render被调用');
        return (
            <div>
                <p>{this.state.age}</p>
                <button onClick={()=>{this.btnClick()}}>APP按钮</button>
            </div>
        )
    }
    /*
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log(this.state.age, nextState.age); // 0 1 //1 1
        if(this.state.age !== nextState.age){
            return true;
        }
        return false;
    }
    */
    btnClick(){
        // 以下两种写法区别:
        // 上面一种方式是设置了一个新的对象
        // 下面这种方式是设置了以前的对象

        // this.setState({
        //     age:this.state.age + 1
        // })
        this.state.age = this.state.age + 1;
        this.setState(this.state);
    }
}
export default App;

react获取元素

1.React中获取元素的方式

  • 字符串
  • 对象
  • 回调函数
import React from "react"

class App extends React.Component {
    constructor () {
        super()
        this.oPRef = React.createRef()
        this.oDRef = null
    }
    render() {
        console.log('App-render')
        return (
            <div>
                {/* <div id={'box'}>p</div> */}
                {/* <div ref={'box'}>p</div> */}
                {/* <div ref={this.oPRef}>p</div> */}
                <div ref={(arg) => { this.oDRef = arg }}>p</div>
                <button onClick={() => this.showHome()}>App按钮</button>
            </div>
        )
    }
    showHome() {
        console.log('点击了')
        // 第一种获取方式: 传统方式(在react中不推荐)
        // const box = document.getElementById('box')
        // 第二种获取方式: 通过ref='字符串'
        // const box = this.refs.box // refs被弃用
        // 第三种方式:通过React.createRef()创建一个对象,然后将这个对象传递给ref (推荐)
        // const box = this.oPRef.current
        // 第四种获取方式:通过传递一个回调函数,然后保存回调函数参数的方式(推荐)
        const box = this.oDRef
        box.innerHTML = 'div'
    }
}
export default App

注意点

  • 获取原生元素,拿到的是元素本身
  • 获取类组件元素,拿到的是组件实例对象
  • 获取函数组件元素,拿不到任何内容
import React from "react"
class Home extends React.PureComponent {
    render() {
        return (
            <div>Home</div>
        )
    }
}
function About() {
    return (
        <div>About</div>
    )
}
class App extends React.Component {
    constructor () {
        super()
        this.oPRef = React.createRef()
        this.oDRef = null
    }
    render() {
        console.log('App-render')
        return (
            <div>
                {/* <div id={'box'}>p</div> */}
                {/* <div ref={'box'}>p</div> */}
                {/* <div ref={this.oPRef}>p</div> */}
                {/* <div ref={(arg) => { this.oDRef = arg }}>p</div> */}
                {/* <Home ref={this.oPRef} /> */}
                <About ref={this.oPRef} />
                <button onClick={() => this.showHome()}>App按钮</button>
            </div>
        )
    }
    showHome() {
        console.log('点击了')
        // const box = document.getElementById('box')

        // const box = this.refs.box // refs被弃用
        // const box = this.oPRef.current
        // const box = this.oDRef
        // box.innerHTML = 'div'
        const Home = this.oPRef.current // 类组件:组件实例;函数组件:null
        console.log('Home', Home)
    }
}
export default App

image.png

Ref转发

1.直接通过ref获取不到函数式组件 2.如果要获取的不是函数式组件本身,而是想获取函数式组件中的某个元素,可以使用Ref转发来获取

React.forwardRef

import React from "react"
class Home extends React.PureComponent {
    render() {
        return (
            <div>Home</div>
        )
    }
}
// function About() {
//     return (
//         <div>About</div>
//     )
// }
const About = React.forwardRef(function (props, myRef) { // myRef === my.oPRef
    return (
        <div>
            <p>About</p>
            <p ref={myRef}>About-myRef</p>
        </div>
    )
})
class App extends React.Component {
    constructor () {
        super()
        this.oPRef = React.createRef()
        this.oDRef = null
    }
    render() {
        console.log('App-render')
        return (
            <div>
                {/* <div id={'box'}>p</div> */}
                {/* <div ref={'box'}>p</div> */}
                {/* <div ref={this.oPRef}>p</div> */}
                {/* <div ref={(arg) => { this.oDRef = arg }}>p</div> */}
                {/* <Home ref={this.oPRef} /> */}
                <About ref={this.oPRef} />
                <button onClick={() => this.showHome()}>App按钮</button>
            </div>
        )
    }
    showHome() {
        console.log('点击了')
        // const box = document.getElementById('box')

        // const box = this.refs.box // refs被弃用
        // const box = this.oPRef.current
        // const box = this.oDRef
        // box.innerHTML = 'div'
        const About = this.oPRef.current // 类组件:组件实例;函数组件:null
        console.log('About', About)
    }
}
export default App

受控组件

import React from "react"
class App extends React.PureComponent {
    constructor (props) {
        super(props)
        this.state = {
            name: 'study',
            email: '123456@qq.com',
            phone: '110'
        }
    }
    render() {
        return (
            <form>
                <input type="text" name={'name'} value={this.state.name} onChange={(e) => { this.change(e) }} />
                <input type="text" name={'email'} value={this.state.email} onChange={(e) => { this.change(e) }} />
                <input type="text" name={'phone'} value={this.state.phone} onChange={(e) => { this.change(e) }} />
            </form>
        )
    }
    change(e) {
        console.log('e.target.name', e.target.name)
        this.setState({
            [e.target.name]: e.target.value
        })
    }
}
export default App

非受控组件

class App extends React.PureComponent {
    constructor (props) {
        super(props)
        this.myRef = React.createRef()

    }
    render() {
        return (
            <form onSubmit={(e) => { this.submit(e) }}>
                <input type="text" ref={this.myRef} />
                <input type="submit" />
            </form>
        )
    }
    submit(e) {
        e.preventDefault()
        console.log('this.myRef', this.myRef.current.value)
    }
}

高阶组件

import React from "react"
import { EventEmitter } from "events"
const AllContext = React.createContext({})
const { Provider, Consumer } = AllContext
const eventBus = new EventEmitter()
class Home extends React.PureComponent {
    render() {
        return (
            <div>
                <div>{this.props.dom}</div>
                <div>{this.props.label}</div>
            </div>
        )
    }
}
class Header extends React.PureComponent {
    render() {
        return (
            <div>
                <div>{this.props.dom}</div>
                <div>{this.props.label}</div>
                {
                    this.props.list.map(name => {
                        return <li key={name}>{name}</li>
                    })
                }
            </div>
        )
    }
}

function enhancedComponent(WrappedComponent) {
    class AdvComponent extends React.PureComponent {
        constructor (props) {
            super(props)
            this.state = {
                list: []
            }
        }
        componentDidMount() {
            eventBus.addListener('update', this.update.bind(this))
        }
        componentWillUnmount() {
            eventBus.removeListener('update', this.update.bind(this))
        }
        update(list) {
            this.setState({
                list: list
            })
        }
        render() {
            return (
                <Consumer>
                    {
                        (value) => {
                            return (
                                <WrappedComponent {...value} {...this.props} {...this.state} />
                            )
                        }
                    }
                </Consumer>

            )
        }
    }
    return AdvComponent
}
const HomeComponent = enhancedComponent(Home)
const HeaderComponent = enhancedComponent(Header)
class App extends React.PureComponent {
    render() {
        return (
            <div>
                <Provider value={{ dom: 'DOM' }}>
                    <HomeComponent label={'Home'}></HomeComponent>
                    <hr />
                    <HeaderComponent label={'Header'}></HeaderComponent>
                </Provider>
                <button onClick={this.btnClick.bind(this)}>展示数据</button>
            </div>
        )
    }
    btnClick() {
        eventBus.emit('update', ['好好', '学习', '天天'])
    }
}
export default App 
class Info extends React.PureComponent{
    render() {
        return (
            <div>用户信息</div>
        )
    }
}
class Login extends React.PureComponent{
    render() {
        return (
            <div>用户登录</div>
        )
    }
}
function EnhancedComponent (WrappedComponent) {
    class Authority extends React.PureComponent{
        render() {
            if(this.props.isLogin){
                return <Info/>
            }else{
                return <Login/>
            }
        }
    }
    return Authority;
}
const AuthorityInfo = EnhancedComponent(Info);

class App extends React.PureComponent{
    constructor(props){
        super(props);
    }
    render(){
        return (
            <AuthorityInfo isLogin={true}/>
        )
    }
}

Fragment

import React from "react"
class Home extends React.PureComponent {
    constructor (props) {
        super(props)
        this.state = {
            heroList: ['张大', '王大', '李达']
        }
    }
    render() {
        return (
            // this.state.heroList.map(name => {
            //     return (
            //         <p key={name}>{name}</p>
            //     )
            // })
            // <>
            //     {
            //         this.state.heroList.map(name => {
            //             return (
            //                 <p key={name}>{name}</p>
            //             )
            //         })
            //     }
            // </>
            <>
                {
                    this.state.heroList.map(name => {
                        return (
                            <React.Fragment key={name}>
                                <p>{name}</p>
                            </React.Fragment>
                        )
                    })
                }
            </>
        )
    }
}
class App extends React.PureComponent {
    render() {
        return (
            <>
                <p>12</p>
                <Home />
            </>
        )
    }
}
export default App