关于React入门基础从哪学起?


前言

英文官网
中文官网

自己整理的react文档,结合官网和所学知识的一个总结希望对各位有用。话不多说看下文:


一、React简介

1. React是什么

**React**: 用于构建用户界面的 JavaScript 库

2. react 与 vue 最大的区别就是:

在表层上,模板的语法不同,React是通过JSX渲染模板。. 而Vue是通过一种拓展的HTML语法进行渲染,但其实这只是表面现象,毕竟React并不必须依赖JSX。. 在深层上,模板的原理不同,这才是他们的本质区别:React是在组件JS代码中,通过原生JS实现模板中的常见语法,比如插值,条件,循环等,都是通过JS语法实现的,更加纯粹更加原生。. 而Vue是在和组件JS代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要 v-if 来实现对这一点,这样的做法显得有些独特,会把HTML弄得很乱。

3. React特点

在这里插入图片描述

4. React介绍描述

		1.用于动态构建用户界面的 JavaScript 库(只关注于视图)
		2.由Facebook开源

5. React高效的原因

		1.使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。
		2.DOM Diffing算法, 最小化页面重绘。
		关于虚拟DOM:
		1.本质上是object类型的对象(一般对象)
		2.虚拟DOM比较轻,真实DOM比较重。因为虚拟DOM

6.React强大之处

速度快

它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好

很好的跨浏览器兼容

虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。

所有都是component:

组件化的代码更加模块化,重用代码更容易,可维护性高。

单向数据流

Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。

兼容性好

比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏

二、React基础格式

<!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>Document</title>
</head>

<body>
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="./js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="./js/react-dom.development.js"></script>
    <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

    <script src="./js/babel.min.js"></script>
    <script type="text/babel">
            // 1.创建虚拟 dom
            const VDOM = <h1>hello word</h1>

            // 2.渲染到页面中的指定dom
            // ReactDOM.render(虚拟dom,真实dom)
            ReactDOM.render(VDOM,document.getElementById('test'))


    </script>
</body>

</html>

讲解: 首先我们需要完成基础引入react。然后先创建一个虚拟dom再把虚拟dom在指定元素里渲染成真实dom

1.什么是虚拟dom?

什么是虚拟 DOM? 在 React 中,render 执行的结果得到的并不是真正的 DOM 节点,结果仅仅是轻量级的 JavaScript 对象,我们称之为 virtual DOM。 虚拟 DOM 是 React 的一大亮点,具有 batching (批处理) 和高效的 Diff 算法。

2.为什么要创建虚拟dom?

我们知道,虚拟DOM的概念是由Facebook的React团队最早提出来的,也是React框架的核心概念之一。 它的作用是以js的形式在内存中描述真实的DOM结构,这样当页面内容需要发生变动时,React可以通过对前后虚拟DOM的比对,计算出如何以最小的代价操作真实DOM。

三、React也分为俩种创建方式

1. 使用js的方式来创建

声明 不建议使用 。 代码多

<!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>Document</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>

    <script type="text/javascript">
        // 1.创建虚拟 dom
        // const VDOM = React.createElement(标签名,标签属性,标签内容)
        const VDOM = React.createElement('h1', {
    
     id: "title" }, React.createElement('span',{
    
    },"hello react"))


        // 2.渲染到页面中的指定dom
        // ReactDOM.render(虚拟dom,真实dom)
        ReactDOM.render(VDOM, document.getElementById('test'));


    </script>
</body>

</html>

2.使用jsx方式创建

声明 建议使用 它会自动转换成js格式 代码简洁(它没有this指向 需要自己绑定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>Document</title>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>
     <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

            <script src="../js/babel.min.js"></script>

    <script type="text/babel">
        // 1.创建虚拟 dom
        // const VDOM = React.createElement(标签名,标签属性,标签内容)
        const VDOM = (
            <h1>hello
                <span>react-dom</span>
            </h1>
        )


        // 2.渲染到页面中的指定dom
        // ReactDOM.render(虚拟dom,真实dom)
        ReactDOM.render(VDOM, document.getElementById('test'));


    </script>
</body>

</html>

四、jsx的语法规则

<!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>Document</title>
    <style>
        .title{
    
    
            color: aliceblue;
        }
    </style>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        let myData = 'Student';
        let idData = 'zhongwu';
        // 1.创建虚拟 dom
        // const VDOM = React.createElement(标签名,标签属性,标签内容)
        const VDOM = (
            <div>
                <h1 className="title" id={
    
    idData}>
                    hello,                                                            
                    <span>{
    
     myData }</span>
                    <input type="text"></input>
                    <Good />
                </h1>
            </div>
        )


        // 2.渲染到页面中的指定dom
        // ReactDOM.render(虚拟dom,真实dom)

        ReactDOM.render(VDOM,document.getElementById('test'));

    </script>
</body>

</html>

注意:
jsx的语法规则:
1.定义虚拟dom时,不要用引号;
2.标签中混入js表达式时,要用{}
3.样式的类名指定不要用class要用className;
4.内联样式,要用style={ {key:value}}的形式去写
5.只能有一个根元素
6所有标签都必须要闭合
7. 标签的首字母:
1.若是小写字母开头,则将改标签转化为html同名的元素,渲染到页面
若html没有同名的元素,则报错

                           2.若大写字母开头,react就会去渲染对应的组件,若组件没有定义,则报错;
        /

五、react定义组件

**声明:**组件化是React的核心思想,也是我们后续课程的重点,前面我们封装的App本身就是一个组件: 组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。 任何的应用都会被抽象成一颗组件树。 有了组件化的思想,我们在之后的开发中就要充分的利用它。 尽可能的将页面拆分成一个个小的、可复用的组件。 这样让我们的代码更加方便组织和管理,并且扩展性也更强。 React的组件相对于Vue更加的灵活和多样,按照不同的方式可以分成很多类组件: 这些概念有很多重叠,但是他们最主要是关注数据逻辑和UI展示的分离: 当然还有很多组件的其他概念:比如异步组件、高阶组件等,我们后续再学习。

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>Document</title>
    <style>
        .title {
    
    
            color: aliceblue;
        }
    </style>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        // 1.创建函数式组件
        function MyComponent() {
    
    

                console.log(this)//undefined ,因为babel编译,开启了严格模式

            // 一定需要有返回值
            return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
        }



        // 2.渲染到页面中的指定dom
        // ReactDOM.render(虚拟dom,真实dom)

        ReactDOM.render(<MyComponent />, document.getElementById('test'));

        /*
            执行ReactDOM.render()方法之后,发生了什么?

            1.React解析了组件标签,找到了对应的组件
            2.发现这个组件是一个函数定义的 随后调用改函数,生成了一个虚拟dom
            3.最后将虚拟dom转化为真实dom,呈现在页面中
        
        
        */


    </script>
</body>

</html>

2.类式组件

<!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>Document</title>
    <style>
      
    </style>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        // 1.创建一个 类式组件
        class MyComponent extends React.Component{
    
    

            //render方法是放在原型上
            // render中的this是谁?  ---实例对象
            render(){
    
    
                console.log('render中的this',this)
                return  <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>
            }

        }
 
        ReactDOM.render(<MyComponent />, document.getElementById('test'));

         /*
            执行ReactDOM.render()方法之后,发生了什么?

            1.React解析了组件标签,找到了对应的组件
            2.发现这个组件是一个类定义的 随后new出来一个实例对象并通过该实例对象调用原型上的render方法
            3.最将render() 返回的内容生成一个虚拟dom
            4.最后将虚拟dom转化为真实dom,呈现在页面中
        
        
        */
     
        let c = new MyComponent();
        console.log(c)

    </script>
</body>

</html>

3.函数式组件和类式组件的区别

1、函数组件是一个纯函数,它接收一个props对象返回一个react元素;而类组件需要去继承React.Component并且创建render函数返回react元素。
2、函数组件没有生命周期和状态state,而类组件有。
3、 官方建议使用函数式组件

六、 组件实例的三大属性

1.state

声明:
状态( state )即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
通过 this.state 来获取状态
通过setState修改state数据(注意: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>Document</title>
    <style>

    </style>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="test"></div>
    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持忍让传统操作dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入 babel
            1.es6 ==> es5
            2.jsx ==>js -->

    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        // 1.创建一个 类式组件
        class Weather extends React.Component {
    
    
            state = {
    
     isTian: true, wind: '微风' };

            render() {
    
    
                let {
    
     isTian, wind } = this.state;
                return <h2 onClick={
    
    this.changewWeather}>今天天气很爽 {
    
    isTian ? "不冷" : "不热"},{
    
    wind}</h2> //istian
            }




            changewWeather = () => {
    
    

                let {
    
     isTian } = this.state;

                this.setState({
    
     isTian: !isTian })//这里的修改,是覆盖还是合并?


            }

        }

        ReactDOM.render(<Weather />, document.getElementById('test'));





    </script>
</body>

</html>

2.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>Document</title>
</head>
<style>
    .title {
    
    
        color: aqua;
    }
</style>

<body>
    <div id="test">

    </div>
    <div id="test1">

    </div>
    <div id="test2">

    </div>
    <!-- 引入React核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 操作dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入babel ES6==>ES5  JSX==>JS -->
    <script src="../js/babel.min.js"></script>
    <script type="text/babel">
        class Weather extends React.Component {
    
    
            constructor(props) {
    
    //是否接受,取决于是否使用外部数据
                super(props)//只能上面接受了props,super()就去传递,否则后续的使用,可能就会出现问题

            }
            static propTypes = {
    
    
                name: PropTypes.string.isRequired,//限制name为字符串类型,必填
                // age: PropTypes.number,
                sex: PropTypes.string,
                speak: PropTypes.func
            }
            static defaultProps = {
    
    
                sex: '男',
            }

            render() {
    
    
                let {
    
     name, age, sex } = this.props
                return (
                    <ul>
                        <li>姓名:{
    
    name}</li>
                        <li>性别:{
    
    sex}</li>
                        <li>年龄:{
    
    age + 1}</li>
                    </ul>
                )
            }
        }
        /*
            问题:
                1.数据类型是否有对应的限制?
                2.数据的数量 批量传输可以使用展开运算符
        */
        ReactDOM.render(<Weather name="tom" age={
    
    26} sex="女" />, document.getElementById('test'))

    </script>
</body>

</html>

3、ref

**声明:**在典型的 React 数据流中,props 是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的 props 来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素。对于这两种情况,React 提供了使用ref来解决它。

作者:智慧女孩要秃头
链接:https://juejin.cn/post/7047113456993959972
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        class Person extends React.Component {
    
    

            showData = () => {
    
    
                //转款专用:每一个ref都是唯一的,存在this.refs中
                let {
    
     ipt } = this.refs;
                alert(ipt.value)
            }

            getData=()=>{
    
    
                let {
    
     ipt1 } = this.refs;
                alert(ipt1.value)
            }
            render() {
    
    
                return (
                    <div>
                        <input ref='ipt' type="text" placeholder="请输入数量" />
                        <button onClick={
    
    this.showData}>点我提示左侧的数据</button>
                        <input onClick={
    
    this.getData} ref='ipt1' type="text" placeholder="请输入数量" />
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

七 、事件处理

声明: 1.通过onXxx属性指定事件处理函数(注意大小写)
1)React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 —为了更好的兼容性
2)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) —为了更加高效
2.通过event.target得到发生事件的DOM元素对象 — 勿过度使用 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>ref</title>
</head>

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

    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        class Person extends React.Component {
    
    





            myRef = React.createRef(); //容量为1,只能存一个,多余会覆盖前者
            myRef1 = React.createRef();

            showData = (event) => {
    
    
                alert(this.myRef.current.value)
                console.log(event.target)
            }
            showData1 = () => {
    
    
                alert(this.myRef1.current.value)
            }

// 回调函数
            // 1.自己写的函数
            // 2.不是自己调用的
            // 3.这个函数最后执行了

            render() {
    
    
                return (
                    <div>
                        {
    
    /* 这里是jsx注释 */}
                        <input ref={
    
    this.myRef} type="text" placeholder="请输入数量" />
                        <button onClick={
    
    this.showData}>点我提示左侧的数据</button>
                        <input onBlur={
    
    this.showData1} ref={
    
    this.myRef1} type="text" placeholder="请输入数量" />
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

八、react收集表单

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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

        class Person extends React.Component {
    
    

         
            handler=(event)=>{
    
    
                event.preventDefault();//阻止默认事件 --- 阻止表单跳转
                    let {
    
    username,password} = this;
                    alert(`你输入的名字${
     
     username.value},密码是${
     
     password.value}`)
            }
            render() {
    
    
                return (
                    <div>
                        <form action="https://www.baidu.com" onSubmit={
    
    this.handler}>
                            用户名:<input type="text" name='username' ref={
    
     c =>this.username=c} />
                            密码:<input type="text" name="password" ref={
    
     c =>this.password=c } />
                            <button type="submit">登录</button>
                        </form>
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

2.受控组件

**声明:**表单项输入数据能自动收集成状态,

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">




        //受控组件
        class Person extends React.Component {
    
    
            //初始化状态
            state = {
    
    
                username: '',//用户名
                password: ''//密码
            }
            //保存用户名到状态中
            saveUsername = (event) => {
    
    
                this.setState({
    
     username: event.target.value })
            }

            //保存密码到状态中
            savePassword = (event) => {
    
    
                this.setState({
    
     password: event.target.value })
            }


            //表单提交回调
            handler = (event) => {
    
    
                event.preventDefault();//阻止默认事件 --- 阻止表单跳转
                let {
    
     username, password } = this.state;
                alert(`你输入的名字${
     
     username},密码是${
     
     password}`)
            }
            render() {
    
    
                return (
                    <div>
                        <form action="https://www.baidu.com" onSubmit={
    
    this.handler}>
                            用户名:<input type="text" name='username' onChange={
    
    this.saveUsername} />
                            密码:<input type="text" name="password" onChange={
    
    this.savePassword} />
                            <button type="submit">登录</button>
                        </form>
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

九、高阶函数

1.高阶函数

声明:
高阶函数:如果一个函数符合下面2个规范中的任何一个,那么它就是属于一个高阶函数
1.若A函数,接受的参数是一个函数,那么A就可以称为高阶函数
2.若A函数,调用的返回值依然是一个函数,那么A也可以称为高阶函数

    常见的高阶函数:Promise,setTimeout,arr.map回调函数等等

函数柯里化:通过函数的继续调用 返回值为函数的方式,实现的多次接收参数,最会统一处理的函数编码形式

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

/*
region


                 function sum(a){
    
    
                return (b)=>{
    
    
                    return (c)=>{
    
    
                        return a+b+c;
                    }
                }
            }

*/


        //受控组件
        class Person extends React.Component {
    
    
            //初始化状态
            state = {
    
    
                username: '',//用户名
                password: ''//密码
            }
            //保存用户名到状态中
            saveUsername = (event) => {
    
    
                this.setState({
    
     username: event.target.value })
            }

            //保存密码到状态中
            savePassword = (event) => {
    
    
                this.setState({
    
     password: event.target.value })
            }


            //保存表单数据到状态中
            saveFormData = (dataType) => {
    
    //这里传来的是标识  标识当前标签
                return (event)=>{
    
     //这里的回调谁执行?? input标签的 onchange事件
                   
                    // console.log(event.target.value,'@@@')
                        this.setState({
    
    
                            [dataType]: event.target.value
                        })
                        // console.log(dataType) // username password 
                }

            }
            //表单提交回调
            handler = (event) => {
    
    
                event.preventDefault();//阻止默认事件 --- 阻止表单跳转
                let {
    
     username, password } = this.state;
                alert(`你输入的名字${
     
     username},密码是${
     
     password}`)
            }
            render() {
    
    
                return (
                    <div>
                        <form action="https://www.baidu.com" onSubmit={
    
    this.handler}>
                            用户名:<input type="text" name='username' onChange={
    
    this.saveFormData('username')} />
                            密码:<input type="text" name="password" onChange={
    
    this.saveFormData('password')} />
                            <button type="submit">登录</button>
                        </form>
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

2.函数柯里化

声明:
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">

     


        //受控组件
        class Person extends React.Component {
    
    
            //初始化状态
            state = {
    
    
                username: '',//用户名
                password: ''//密码
            }
            //保存用户名到状态中
            saveUsername = (event) => {
    
    
                this.setState({
    
     username: event.target.value })
            }

            //保存密码到状态中
            savePassword = (event) => {
    
    
                this.setState({
    
     password: event.target.value })
            }


            //保存表单数据到状态中
            saveFormData = (dataType, event) => {
    
    //这里传来的是标识  标识当前标签

                this.setState({
    
    
                    [dataType]: event.target.value
                })



            }
            //表单提交回调
            handler = (event) => {
    
    
                event.preventDefault();//阻止默认事件 --- 阻止表单跳转
                let {
    
     username, password } = this.state;
                alert(`你输入的名字${
     
     username},密码是${
     
     password}`)
            }
            render() {
    
    
                return (
                    <div>
                        <form action="https://www.baidu.com" onSubmit={
    
    this.handler}>
                            用户名:<input type="text" name='username' onChange={
    
    event => this.saveFormData('username', event)} />
                            密码:<input type="text" name="password" onChange={
    
    event => this.saveFormData('password', event)} />
                            <button type="submit">登录</button>
                        </form>
                    </div>
                )
            }
        }


        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

十、 组件的生命周期

1.什么是组件的生命周期:

组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程

2.钩子函数的作用:

为开发人员在不同阶段操作组件提供了时机。

3.生命周期的意义:

有助于理解组件的运行方式
完成更复杂的组件功能
分析组件错误原因等

4.生命周期使用场景

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">
        // 1.创建虚拟 dom


                // 1. 生命周期回调函数 === 生命周期钩子函数 === 生命周期函数 === 生命周期钩子

        class Person extends React.Component {
    
    
            state = {
    
    
                opacity: 1
            }

            constructor(){
    
    
                super();
                console.log('constructor')
            }

            //组件将要挂载
            componentWillMount(){
    
    
                console.log("componentWillMount")
            }

            //组件将要卸载
            componentWillUnmount(){
    
    
                console.log("啊 我Neo写咋")
                clearInterval(this.timer)
            }

            //组件挂载完成之后
            componentDidMount() {
    
    
                console.log("componentDidMount")
                setInterval(() => {
                    // 获取原状态

                    let { opacity } = this.state;
                    opacity -= 0.1;
                    if (opacity <= 0) opacity = 1;
                    //设置新透明度
                    this.setState({ opacity });

                }, 200)

            }

            death=()=>{
                //卸载组件
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }
            render() {
    
    
                console.log("render")

                return (
                    <div>
                        <span style={
    
    {
    
     opacity: this.state.opacity } } >学不会React怎么办</span>
                        <button onClick={
    
    this.death}>按钮</button>
                    </div>
                )
            }


        }
        // 2.渲染到页面中的指定dom
        ReactDOM.render(<Person />, document.getElementById('test'))

    </script>
</body>

</html>

5.react 生命周期(旧)

在这里插入图片描述

生命周期的三个阶段(旧)
1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
1.constructor()
2.componentWillMount()
3.render()
4.componentDidMount()
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
1.shouldComponentUpdate()
2.componentWillUpdate()
3.render()
4.componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount()

<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">


        /*
        1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
          1.constructor()
          2.componentWillMount()
          3.render()
          4.componentDidMount() === >常用:
                            一般在这个钩子中做一些初始化的事情:例如:开启定时器,发送网络请求


        2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
            1.shouldComponentUpdate()
            2.componentWillUpdate()
            3.render()   ===》必须使用
            4.componentDidUpdate() 


        3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
            1.componentWillUnmount() ===》常用
                一般在中国函数中做一些收尾的事,例如:关闭定时器 取消订阅

        */

        class Person extends React.Component {
    
    

            state = {
    
     count: 0 }

            // 点我
            add = () => {
    
    
                //获取原状态
                let {
    
     count } = this.state;
                // 更新状态
                this.setState({
    
     count: count + 1 });
            }

            // 卸载组件
            death = () => {
    
    
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            force = () => {
    
    
                this.forceUpdate()
            }

            // 数据更新的 '阀门'
            shouldComponentUpdate = () => {
    
    
                console.log("count ------ shouldComponentUpdate")
                return true; //这里必须有返回值,其次返回值默认为true
            }

            // 组件将要更新的钩子
            componentWillUpdate() {
    
    
                console.log("count ----   componentWillUpdate")
            }

            // 组件更新完毕的钩子
            componentDidUpdate() {
    
    
                console.log("count ---- componentDidMount")
            }
            render() {
    
    
                return (
                    <div>
                        <h2>当前求和为:{
    
    this.state.count}</h2>
                        <button onClick={
    
    this.add}>点我+1</button>
                        <button onClick={
    
    this.death}>卸载组件</button>
                        <button onClick={
    
    this.force}>不更改任何状态中的数据,强制更新</button>
                    </div>
                )
            }
        }


        // 父组件

        class A extends React.Component {
    
    
            state = {
    
     carName: "电动车" }
            changeCar = () => {
    
    
                this.setState({
    
     carName: '飞机' });
            }
            render() {
    
    
                console.log("render")
                return (
                    <div>
                        <span>我是a组件</span>
                        <button onClick={
    
    this.changeCar}>换车</button>
                        <B carName={
    
    this.state.carName} />
                    </div>
                )
            }
        }

        // 子组件
        class B extends A {
    
    

            //组件将要接收新的props 的钩子
            componentWillReceiveProps() {
    
    
                console.log("B ---- componentWillReceiveProps ")
            }
            // 数据更新的 '阀门'
            shouldComponentUpdate = () => {
    
    
                console.log("count ------ shouldComponentUpdate")
                return true; //这里必须有返回值,其次返回值默认为true
            }

            // 组件将要更新的钩子
            componentWillUpdate() {
    
    
                console.log("count ----   componentWillUpdate")
            }

            // 组件更新完毕的钩子
            componentDidUpdate() {
    
    
                console.log("count ---- componentDidMount")
            }
            render() {
    
    

                return (
                    <div>
                        我是b组件,接收到的车是:{
    
    this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />, document.getElementById('test'))

    </script>
</body>

</html>

6.React 生命周期(新)

在这里插入图片描述

生命周期的三个阶段(新)

  1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
    1.constructor()
    2.getDerivedStateFromProps
    3.render()
    4.componentDidMount()
    2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
    1.getDerivedStateFromProps
    2.shouldComponentUpdate()
    3.render()
    4.getSnapshotBeforeUpdate
    5.componentDidUpdate()
    3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
    1.componentWillUnmount()
<!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>ref</title>
</head>

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

    <!-- 引入 React 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom 用于支持 react 操作 DOM -->
    <script src="../js/react-dom.development.js"></script>

    <!-- 引入babel:
            1. ES6 ==> ES5
            2. jsx ==> js
    -->
    <script src="../js/babel.min.js"></script>

    <script type="text/babel">


        /*
        1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
          1.constructor()
          2.componentWillMount()
          3.render()
          4.componentDidMount() === >常用:
                            一般在这个钩子中做一些初始化的事情:例如:开启定时器,发送网络请求


        2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
            1.shouldComponentUpdate()
            2.componentWillUpdate()
            3.render()   ===》必须使用
            4.componentDidUpdate() 


        3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
            1.componentWillUnmount() ===》常用
                一般在中国函数中做一些收尾的事,例如:关闭定时器 取消订阅

        */

        class Person extends React.Component {
    
    

            state = {
    
     count: 0 }

            // 点我
            add = () => {
    
    
                //获取原状态
                let {
    
     count } = this.state;
                // 更新状态
                this.setState({
    
     count: count + 1 });
            }

            // 卸载组件
            death = () => {
    
    
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            force = () => {
    
    
                this.forceUpdate()
            }

            // 数据更新的 '阀门'
            shouldComponentUpdate = () => {
    
    
                console.log("count ------ shouldComponentUpdate")
                return true; //这里必须有返回值,其次返回值默认为true
            }

            // 组件将要更新的钩子
            componentWillUpdate() {
    
    
                console.log("count ----   componentWillUpdate")
            }

            // 组件更新完毕的钩子
            componentDidUpdate() {
    
    
                console.log("count ---- componentDidMount")
            }
            render() {
    
    
                return (
                    <div>
                        <h2>当前求和为:{
    
    this.state.count}</h2>
                        <button onClick={
    
    this.add}>点我+1</button>
                        <button onClick={
    
    this.death}>卸载组件</button>
                        <button onClick={
    
    this.force}>不更改任何状态中的数据,强制更新</button>
                    </div>
                )
            }
        }


        // 父组件

        class A extends React.Component {
    
    
            state = {
    
     carName: "电动车" }
            changeCar = () => {
    
    
                this.setState({
    
     carName: '飞机' });
            }

            static getDerivedStateFromProps(props,state){
    
    

                // 这里必须要一个返回值 ==》 state or null
            // 这里的state会覆盖原本的状态,并且后续也无法修改

            // 能将外部的接受的props 赋值给 组件自身的 state
            // 如果你希望自身的state 一直 全部依赖于外部的props,那么可以使用这个生命周期函数
             return{
    
    carName:'qq'}
            }


            // 获取数据
            getSnapshotBeforeUpDate(prevState,prevProps){
    
    

            }
            render() {
    
    
                console.log("A --- render")
                return (
                    <div>
                        <span>我是a组件</span>
                        <button onClick={
    
    this.changeCar}>换车</button>
                        <B carName={
    
    this.state.carName} />
                    </div>
                )
            }
        }

        // 子组件
        class B extends A {
    
    

            //组件将要接收新的props 的钩子
            componentWillReceiveProps() {
    
    
                console.log("B ---- componentWillReceiveProps ")
            }
            // 数据更新的 '阀门'
            shouldComponentUpdate = () => {
    
    
                console.log("count ------ shouldComponentUpdate")
                return true; //这里必须有返回值,其次返回值默认为true
            }

            // 组件将要更新的钩子
            componentWillUpdate() {
    
    
                console.log("count ----   componentWillUpdate")
            }

            // 组件更新完毕的钩子
            componentDidUpdate() {
    
    
                console.log("count ---- componentDidMount")
            }
            render() {
    
    

                return (
                    <div>
                        我是b组件,接收到的车是:{
    
    this.props.carName}
                    </div>
                )
            }
        }

        ReactDOM.render(<A />, document.getElementById('test'))

    </script>
</body>

</html>

7. 重要的勾子

1.render:初始化渲染或更新渲染调用
2.componentDidMount:开启监听, 发送ajax请求
3.componentWillUnmount:做一些收尾工作, 如: 清理定时器

8. 即将废弃的勾子

1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。


总结

以上为react的基础知识,代码里面有注释 。下期出react脚手架。喜欢的话证明自己来过^ - ^

猜你喜欢

转载自blog.csdn.net/www61621/article/details/129795843