React的基本理解使用、组件的三大核心属性

一、 基本理解和使用

1、使用React开发者工具调试

在这里插入图片描述

2、定义组件

2.1、定义函数式组件

2.1.1、执行了ReactDOM. render( …之后,发生了什么?
        1.React解析组件标签,找到了``MyComponent``组件。
        2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面史。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函数组件</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
    //1.创建函数式组件
    function MyCompoent(){
        console.log(this);//此处的this是undefined, 因为babel编译后开启了严格模式
        return <h2>我是用函数式定义的组件(适用于简单组件的定义)</h2>
    }
    //2.渲染组件到页面
    ReactDOM.render(<MyCompoent/>,document.getElementById('test'))

    /* 

    执行了ReactDOM. render( <MyComponent/>.......之后,发生了什么?
            1.React解析组件标签,找到了MyComponent组件。
            2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM,随后呈现在页面史。
    
    */
    </script>
</body>

</html>

在这里插入图片描述

2.2、定义类式组件

2.2.1、执行了ReactDOM. render( MyComponent…之后,发生了什么?
       2.2.1.1、React解析组件标签,找到了``MyComponent``组件。
         2.2.1.2、发现组件是使用类定义的,随后``new出了该类的实例``,并通过该实例调用到了``原型上的render的方法``
          2.2.1.3、将render返回的虚拟DOM转为真实DOM,随后呈现在页面中
2.2.2、render的疑惑🤔

2.2.2.1、render是放在哪里的?-MyComponent的原型对象上,供实例使用
2.2.2.2、render中的this是谁?-MyComponent的的实例对象。MyComponent组件实例对象

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        // 1.创建类式组件
        class MyComponent extends React.Component {
            //构造器继承过来了
            render() {

                console.log('render中的实例对象:',this);
                // render是放在哪里的?-MyComponent的原型对象上,供实例使用。
                // render中的this是谁?-MyComponent的的实例对象。MyComponent组件实例对象
                return <h2>我是用类式定义的组件(适用于复杂组件的定义)</h2>
            } 
        }

        // 2.渲染组件到页面
        ReactDOM.render(<MyComponent />, document.getElementById('test'))
     /* 

    执行了ReactDOM. render( <MyComponent/>.......之后,发生了什么?
            1.React解析组件标签,找到了MyComponent组件。
            2.发现组件是使用类定义的,随后new出了该类的实例,并通过该实例调用到了原型上的render的方法
            3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中
            
    
    */
    </script>
</body>

</html>

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

二、组件的三大核心属性

1、❤️state❤️

1.1、初始化显示页面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
    //1.创建组件
    class Weather extends React.Component{
        constructor(props){
            super(props)
            //初始化状态
            this.state={isSchool:false}
        }
        render() {
            console.log(this);
           return <h1>我想去{this.state.isSchool?'清华大学':'北京大学'}</h1> 
        }

    }

    //2.渲染组件到页面
    ReactDOM.render(<Weather/>,document.getElementById('test'))
    </script>
</body>

</html>

在这里插入图片描述

1.2、this指向问题(点击文本)

解决changeSchool指向问题
类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined

this.changeSchool = this.changeSchool.bind(this)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //1.创建组件
        class School extends React.Component {
            constructor(props) {
                super(props)
                //初始化状态
                this.state = { isSchool: false }
                //解决changeSchool指向问题
                this.changeSchool = this.changeSchool.bind(this)
            }
            render() {
                console.log(this);
                return <h1 onClick={this.changeSchool}>我想去{this.state.isSchool ? '清华大学' : '北京大学'}</h1>
            }
            changeSchool() {
                //changeWeather放在哪里?一Weather的原型对象 上,供实例使用
                //由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
                //类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined

                //    console.log(this.state.isSchool);
                console.log(this);


            }

        }

        //2.渲染组件到页面
        ReactDOM.render(<School />, document.getElementById('test'))


    </script>
</body>

</html>

1.3、state里面不能直接修改状态

3.1.3.1、目标:点击文本修改页面状态

3.1.3.2、里面的constructor、render、changeSchool分别被调用了几次
constructor调用了几次?-----1 次
render调用了几次?-----1+n次 1是初始化的那次 n是状态更新的次数
changeSchool调用了几次?----点击了几次就调用几次
3.1.3.3、严重注意
状态不能直接更改,要借助内置的API。state状态必须通过setState修改,且更新是合并,不是替换

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //1.创建组件
        class School extends React.Component {
            //构造器调用了几次?-----1 次
            constructor(props) {
                console.log('constructor');
                super(props)
                //初始化状态
                this.state = { isSchool: false ,name:'qxt'}
                //解决changeSchool指向问题
                this.changeSchool = this.changeSchool.bind(this)
            }

            //render调用了几次?-----1+n次  1是初始化的那次 n是状态更新的次数
            render() {
                console.log('render');
                console.log(this);
                return <h1 onClick={this.changeSchool}>我想去{this.state.isSchool ? '清华大学' : '北京大学'},{this.state.name}</h1>
            }

             //changeSchool调用了几次?-----点几次调用几次
            changeSchool() {
                console.log('changeSchool');
                //changeWeather放在哪里?一Weather的原型对象 上,供实例使用
                //由于changeWeather是作为onClick的回调,所以不是通过实例调用的,是直接调用
                //类中的方法默认开启了局部的严格模式,所以changeWeather中的this为undefined

                //    console.log(this.state.isSchool);
                console.log(this);
                // 获取原来的isSchool的值
                const isSchool = this.state.isSchool
                

                //严重注意:state状态必须通过setState修改,且更新是合并,不是替换
                this.setState({isSchool:!isSchool})
                console.log(this.state.isSchool);
                
         

                // //严重注意:状态不能直接更改,要借助内置的API,下面这行是直接更改
                       //修改isSchool的状态 点击取反
                // this.state.isSchool = !isSchool


                


            }

        }

        //2.渲染组件到页面
        ReactDOM.render(<School />, document.getElementById('test'))


    </script>
</body>

</html>

请添加图片描述

1.4、state简写方式

3.1.4.1、注意
箭头函数没有this ,里面的this会去外层找到那个this
自定义函数----类里面可以直接赋值
这里面的this去外面找this,就是School实例对象

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //1.创建组件
        class School extends React.Component {
            //初始化状态
            state = { isSchool: false, name: '邱勋涛' }
         
            render() {
                return <h1 onClick={this.changeSchool}>我想去{this.state.isSchool ? '北京电影学院' : '中央戏剧学院'}❤️{this.state.name}❤️</h1>
            }           
             
            // 箭头函数没有this ,里面的this会去外层找到那个this
            // 自定义函数----类里面可以直接赋值 
            // 这里面的this去外面找this,就是School实例对象
            changeSchool=()=> {
                const isSchool = this.state.isSchool
                this.setState({ isSchool: !isSchool })
                console.log(this);
            }

        }

        //2.渲染组件到页面
        ReactDOM.render(<School />, document.getElementById('test'))


    </script>
</body>

</html>

请添加图片描述
调试工具反应会有延迟

1.4、总结

1.4.1、理解

1.state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
2.组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

1.4.2、强烈注意

1.组件中render方法中的this为组件实例对象
2.组件自定义的方法中thisundefined,如何解决?
(a)强制绑定this: 通过函数对象的bind()
(b)箭头函数
3.状态数据,不能直接修改或更新

2、❤️props❤️

2.1、props的基本使用

2.1.1、需求: 自定义用来显示人员信息的组件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
    //创建组件
    class Person extends React.Component{
        render() {

            console.log(this);

            return (
                <ul>
                    <li>姓名:{this.props.name}</li>
                    <li>性别:{this.props.age}</li>
                    <li>年龄:{this.props.sex}</li>
                </ul>
            )
        }
        
    }
    //渲染组件到页面

    ReactDOM.render(<Person name="鹿晗" age='18' sex='男'/>,document.getElementById('test1'))
    ReactDOM.render(<Person name="王嘉尔" age='20' sex='男'/>,document.getElementById('test2'))
    ReactDOM.render(<Person name="胡歌" age='19' sex='男'/>,document.getElementById('test3'))
    ReactDOM.render(<Person name="刘亦菲" age='16' sex='女'/>,document.getElementById('test4'))
    </script>
</body>

</html>

在这里插入图片描述

2.1.2、props批量传递

2.1.2.1、… 展开运算符批量传递props
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
    //创建组件
    class Person extends React.Component{
        render() {

            console.log(this);

            return (
                <ul>
                    <li>姓名:{this.props.name}</li>
                    <li>性别:{this.props.age}</li>
                    <li>年龄:{this.props.sex}</li>
                </ul>
            )
        }
        
    }
    //渲染组件到页面

    ReactDOM.render(<Person name="鹿晗" age='18' sex='男'/>,document.getElementById('test1'))
    ReactDOM.render(<Person name="王嘉尔" age='20' sex='男'/>,document.getElementById('test2'))
    ReactDOM.render(<Person name="胡歌" age='19' sex='男'/>,document.getElementById('test3'))
    const p={name:'刘亦菲',age:16,sex:'女'}
    ReactDOM.render(<Person {...p}/>,document.getElementById('test4'))
    </script>
</body>

</html>
2.1.2.2、对props进行限制

a、第一种方式(React v15.5 开始已弃用)

Person.propTypes = {
            // 限制名字 必须传 字符串
            name: React.PropTypes.string.isRequired,
            //限制性别 字符串
            sex: React.PropTypes.string,
            //限制年龄 数值
            age: React.PropTypes.number,

            //限制函数
            speak:React.PropTypes.func
 
}

b、第二种方式(新):使用prop-types库进限制(需要引入prop-types库
在这里插入图片描述

        //对标签属性进行类型、必要性的限制
Person.propTypes = {
            // 限制名字 必须传 字符串
            name: PropTypes.string.isRequired,
            //限制性别 字符串
            sex: PropTypes.string,
            //限制年龄 数值
            age: PropTypes.number,

            //限制函数
            speak: PropTypes.func
 }

c、props默认属性

Person.defaultProps = {
            //sex 默认值 男
            sex: '男',
            //age 默认值 99
            age: 99
}

d、组件类的构造函数

constructor(props){
  super(props)
  console.log(props)//打印所有属性
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 引入prop-types 用于对组件标签进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //创建组件
        class Person extends React.Component {
            render() {

                console.log(this);
                const { name, age, sex } = this.props

                return (
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{age + 1}</li>
                        <li>年龄:{sex}</li>
                    </ul>
                )
            }

        }
        //对标签属性进行类型、必要性的限制
        Person.propTypes = {
            // 限制名字 必须传 字符串
            name: PropTypes.string.isRequired,
            //限制性别 字符串
            sex: PropTypes.string,
            //限制年龄 数值
            age: PropTypes.number,

            //限制函数
            speak: PropTypes.func
        }

        //指定默认标签属性
        Person.defaultProps = {
            //sex 默认值 不知道
            sex: '不知道',
            //age 默认值 99
            age: 99
        }




        //渲染组件到页面
        ReactDOM.render(<Person name="鹿晗" age={18} sex='男' speak={speak} />, document.getElementById('test1'))
        ReactDOM.render(<Person name="王嘉尔" age={18} sex='男' />, document.getElementById('test2'))
        ReactDOM.render(<Person name="胡歌" age={18} sex='男' />, document.getElementById('test3'))
        const p = { name: 'jerry' }
        ReactDOM.render(<Person {...p} />, document.getElementById('test4'))


        function speak() {
            console.log('我成功了');
        }
    </script>
</body>

</html>
2.1.2.3、props简写方式

把限制props的代码写在类的里面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 引入prop-types 用于对组件标签进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //创建组件
        class Person extends React.Component {
            //对标签属性进行类型、必要性的限制
            static propTypes = {
                // 限制名字 必须传 字符串
                name: PropTypes.string.isRequired,
                //限制性别 字符串
                sex: PropTypes.string,
                //限制年龄 数值
                age: PropTypes.number,

                //限制函数
                speak: PropTypes.func
            }

            //指定默认标签属性
            static defaultProps = {
                //sex 默认值 不知道
                sex: '不知道',
                //age 默认值 99
                age: 99
            }
            render() {

                console.log(this);
                const { name, age, sex } = this.props

                return (
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{age + 1}</li>
                        <li>年龄:{sex}</li>
                    </ul>
                )
            }

        }





        //渲染组件到页面
        ReactDOM.render(<Person name="鹿晗" age={18} sex='男' speak={speak} />, document.getElementById('test1'))
        ReactDOM.render(<Person name="王嘉尔" age={10} sex='男' />, document.getElementById('test2'))
        ReactDOM.render(<Person name="胡歌" age={18} sex='男' />, document.getElementById('test3'))
        const p = { name: 'jerry' }
        ReactDOM.render(<Person {...p} />, document.getElementById('test4'))


        function speak() {
            console.log('我成功了');
        }
    </script>
</body>

</html>
2.1.2.4、类式组件中的constructor构造器与props

(1)、通常,在 React 中,构造函数仅用于以下两种情况:
a、通过给 this.state 赋值对象来初始化内部 state
b、为事件处理函数绑定实例
(2)、构造器是否接收props,是否传递给super,取决于:
是否希望在构造器中通过this访问props

constructor(props){
         super(props)
        console.log('constructor',this.props);
 }
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 引入prop-types 用于对组件标签进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        //创建组件
        class Person extends React.Component {

            constructor(props){
                super(props)
                console.log('constructor',this.props);
            }


            //对标签属性进行类型、必要性的限制
            static propTypes = {
                // 限制名字 必须传 字符串
                name: PropTypes.string.isRequired,
                //限制性别 字符串
                sex: PropTypes.string,
                //限制年龄 数值
                age: PropTypes.number
            }

            //指定默认标签属性
            static defaultProps = {
                //sex 默认值 不知道
                sex: '男',
                //age 默认值 99
                age: 32
            }
            render() {

                console.log(this);
                const { name, age, sex } = this.props

                return (
                    <ul>
                        <li>姓名:{name}</li>
                        <li>性别:{age + 1}</li>
                        <li>年龄:{sex}</li>
                    </ul>
                )
            }

        }

        //渲染组件到页面
        ReactDOM.render(<Person name="鹿晗" />, document.getElementById('test1'))




    </script>
</body>

</html>

在这里插入图片描述

2.1.2.5、函数式组件使用props

(1)、函数式组件只能用props,对类式组件和refs都不能使用,原因是函数式组件可以传参数,接收了props,是一个对象
在这里插入图片描述
(2)、对props进行限制
static关键字改成函数名Person即可,其他的不变

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test1'></div>
    <div id='test2'></div>
    <div id='test3'></div>
    <div id='test4'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <!-- 引入prop-types 用于对组件标签进行限制 -->
    <script type="text/javascript" src="../js/prop-types.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        function Person(props) {
            console.log(props);

            return (
                <ul>
                    <li>姓名:{props.name}</li>
                    <li>性别:{props.age + 1}</li>
                    <li>年龄:{props.sex}</li>
                </ul>
            )
        }


        //对标签属性进行类型、必要性的限制
        Person.propTypes = {
            // 限制名字 必须传 字符串
            name: PropTypes.string.isRequired,
            //限制性别 字符串
            sex: PropTypes.string,
            //限制年龄 数值
            age: PropTypes.number
        }

        //指定默认标签属性
        Person.defaultProps = {
            //sex 默认值 不知道
            sex: '男',
            //age 默认值 99
            age: 32
        }




        //渲染组件到页面
        ReactDOM.render(<Person name="鹿晗" />, document.getElementById('test1'))




    </script>
</body>

</html>

3、❤️refs❤️

3.1、实现效果(ref 字符串类型 目前官方不推荐 以后会废弃)

3.1.1、需求: 自定义组件, 功能说明如下

1.点击按钮, 提示第一个输入框中的值
2. 当第2个输入框失去焦点时, 提示这个输入框中的值

请添加图片描述

3.2、理解Refs的字符串类型

(1)、组件内的标签可以定义ref属性来标识自己
(2)、ref 字符串类型 目前官方不推荐 以后会废弃
(3)、过时 API:String 类型的 Refs
如果你之前使用过 React,你可能了解过之前的 API 中的 string 类型的 ref 属性,例如 “textInput”。你可以通过 this.refs.textInput 来访问 DOM 节点。我们不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        // 1.创建组建

        class Demo extends React.Component {
            // 显示左侧输入框的数据
            showData = () => {
                const { leftInput } = this.refs
                alert(leftInput.value)



            }
            // 显示右侧输入框的失去焦点的数据
            loseFocus = () => {

                const { rightInput } = this.refs
                alert(rightInput.value)
             
            }

            render() {
                return (

                    <div>
                        <input ref='leftInput' type="text" placeholder=" 点志按钮显示数据" />
                        <button onClick={this.showData}>点我提示左侧的数据</button>
                        <input ref='rightInput' onBlur={this.loseFocus} type="text" placeholder=" 失去焦点显示数据" />
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a='111' />, document.getElementById('test'))
    </script>
</body>

</html>

3.3、回调函数形式的ref

关于回调 refs 的说明
如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。

<input ref={ c=>this.leftInput=c}type="text" placeholder=" 点志按钮显示数据" />
<input ref={c=>this.rightInput=c} onBlur={this.loseFocus} type="text" placeholder=" 失去焦点显示数据" />
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id='test'></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>

    <!-- 引入react-dmo 用于react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

    <!-- 引入babel 用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>


    <!-- 此处一定要写babel -->
    <script type="text/babel">
        // 1.创建组建

        class Demo extends React.Component {
            // 显示左侧输入框的数据
            showData = () => {
                const { leftInput } = this
                alert(leftInput.value)



            }
            // 显示右侧输入框的失去焦点的数据
            loseFocus = () => {

                const { rightInput } = this
                console.log(this);
                alert(rightInput.value)
             
            }

            render() {
                return (

                    <div>
                        <input ref={ c=>this.leftInput=c}type="text" placeholder=" 点志按钮显示数据" />
                        <button onClick={this.showData}>点我提示左侧的数据</button>
                        <input ref={c=>this.rightInput=c} onBlur={this.loseFocus} type="text" placeholder=" 失去焦点显示数据" />
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a='111' />, document.getElementById('test'))
    </script>
</body>

</html>

3.4、回调ref调用次数的问题

解决办法:把里面的内联函数变为外面的赋值函数


			saveInput = (c)=>{
				this.input1 = c;
				console.log('@',c);
			}
<input ref={this.saveInput} type="text"/>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>3_回调ref中回调执行次数的问题</title>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>
	
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel">
		//创建组件
		class Demo extends React.Component{

			state = {isHot:false}

			showInfo = ()=>{
				const {input1} = this
				alert(input1.value)
			}

			changeWeather = ()=>{
				//获取原来的状态
				const {isHot} = this.state
				//更新状态
				this.setState({isHot:!isHot})
			}

			saveInput = (c)=>{
				this.input1 = c;
				console.log('@',c);
			}

			render(){
				const {isHot} = this.state
				return(
					<div>
						<h2>今天天气很{isHot ? '炎热':'凉爽'}</h2>
						{/*<input ref={(c)=>{this.input1 = c;console.log('@',c);}} type="text"/><br/><br/>*/}
						<input ref={this.saveInput} type="text"/><br/><br/>
						<button onClick={this.showInfo}>点我提示输入的数据</button>
						<button onClick={this.changeWeather}>点我切换天气</button>
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo/>,document.getElementById('test'))
	</script>
</body>
</html>

3.5、React.createRef()

React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
			myRef = React.createRef()
			myRef2 = React.createRef()
<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>4_createRef</title>
</head>
<body>
	<!-- 准备好一个“容器” -->
	<div id="test"></div>
	
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel">
		//创建组件
		class Demo extends React.Component{
			/* 
				React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
			 */
			myRef = React.createRef()
			myRef2 = React.createRef()
			//展示左侧输入框的数据
			showData = ()=>{
				alert(this.myRef.current.value);
			}
			//展示右侧输入框的数据
			showData2 = ()=>{
				alert(this.myRef2.current.value);
			}
			render(){
				return(
					<div>
						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
	</script>
</body>
</html>

4、❤️React事件处理❤️

        1.通过onXxx属性指定事件处理函数(注意大小写)
            a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件-------为了更好的兼容性
            b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)---为了高效
        2.通过event.target得到发生事件的DOM元素对象--------不要过度使用ref

在这里插入图片描述
event:发生事件的事件源(事件对象)
发生事件的事件源必须是同一个,要不然找不到

            showData2 = (event) => {
                alert(event.target.value);
            }
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>4_createRef</title>
</head>

<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>

    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        //创建组件
        class Demo extends React.Component {
            /* 

            1.通过onXxx属性指定事件处理函数(注意大小写)
                a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件-------为了更好的兼容性
                b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)---为了高效
            2.通过event.target得到发生事件的DOM元素对象--------不要过度使用ref
            
            
            
            */



            /* 
                React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
             */
            myRef = React.createRef()
            myRef2 = React.createRef()
            //展示左侧输入框的数据
            showData = () => {
                alert(this.myRef.current.value);
                console.log(this);
            }
            //展示右侧输入框的数据
            showData2 = (event) => {
                alert(event.target.value);
            }
            render() {
                return (
                    <div>
                        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input onBlur={this.showData2}  type="text" placeholder="失去焦点提示数据" />&nbsp;
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a="1" b="2" />, document.getElementById('test'))
    </script>
</body>

</html>

🌈🌈🌈今天的自学就到这啦🌈🌈🌈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值