react基础语法

什么是 react?

根据官方的介绍,react 是一个用于构建用户界面的库,但是由于react拥有一系列的生态技术(react-router、react-redux),所以,我们一般也会把 react 当做是一个框架。react 是由 facebook 开发的,最早是 facebook 的一个内部项目。原因就是因为该公司对当时市场上所有的 js 框架都不满意,因为当时所有的 js 框架基本都是基于节点的操作。

react 特点

  • 声明式设计:前端多了一个 vm 层,vm 一变化,v 就自动更新。

  • 高效:主要是针对对比之前的 jquery 时代,因为不用手动操作节点了。

  • JSX:在 react 中,通过 JSX 来描述视图。

  • 虚拟DOM:如果每次有一点更新,就立马去操作真实的DOM,这个开销是很大的,所以在 react中,提出了虚拟DOM 的概念,通过 js 对象来描述DOM树结构

  • 单项数据流:

 

      state:驱动应用的数据源

      view:以声明方式将 state 映射到视图

 

      actions:响应在 view 上的用户输入导致的状态变化

简单的单向数据流(unidirectional data flow)是指用户访问 ViewView 发出用户交互的 Action,在 Action里对 State 进行相应更新。State 更新后会触发 View 更新页面的过程。

这样数据总是清晰的单向进行流动,便于维护并且可以预测。

  • diff 算法:当用户对视图进行更新的时候,先去更新虚拟 DOM,这里说的进行更新,不是在原来的树上面进行更新,而是生成一颗新的树,接下来两棵树就可以进行对比,从而找到不一样的地方,进行更新。

react 安装

前期学习基本语法, 使用 cdn 来引入 react

引入的 cdn 如下:

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

    <!-- 引入 React 核心库 -->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <!-- 提供与 DOM 相关的功能 -->
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>

  快速入门示例:

<script type="text/babel">
   // 接收 2 个参数:JSX(视图的描述)、绑定的根元素
   ReactDOM.render(<h1>Hello.react</h1>,document.getElementById('app'));
 </script>

  

在 react 中,实际上是使用的 createElement 方法来创建的虚拟 DOM。

JSX是一种javascript的语法扩展,实际上是在React底层,提供了createElement方法用于创建并返回指定类型的新React元素,我们书写的JSX会被Babel(转代码)转译器转为React.createElement的方法调用

React.createElement(type, [props], [...children]);

  参数说明:type:创建的React元素类型(可选的值有:标签名字符串、React组件)

       props(可选):React元素属性

       children(可选):React元素的子元素

<body>
 <div id="example1"></div>
 <div id="example2"></div>
 <script type="text/babel">
 // ֵ使用JSX来创建元素
 const ele1 = (
 <div>
createElement
 <h1>欢迎学习  React</h1>
 <p>在 React中推荐使用JSX 来描述用户界面</p>
 <ul>
 <li>JSX 执行更快,英文他在编译JavaScript代码后进行了优化<
/li>
 <li>他是类型安全的,在变异过程中就能发现错误</li>
 <li>ֵ使用JSX编写模板更加简单快速</li>
 </ul>
 </div>
 );

 // ֵ使用React.createElement方法创建元素
 const h1 = React.createElement('h1',null,'欢迎学习  React');
 const p = React.createElement('p',null,'在 React中推荐使用JSX 来描述用户界面');
 const li1 = React.createElement('li',null,'JSX 执行更快,英文他在编译JavaScript代码后进行了优化');
 const li2 = React.createElement('li',null,'他是类型安全的,在变异过程中就能发现错误');
 const li3 = React.createElement('li',null,'ֵ使用JSX编写模板更加简单快速');
 const ul = React.createElement('ul',null,li1,li2,li3);
 const ele2 = React.createElement('div',null,h1,p,ul);
 ReactDOM.render(ele1 , document.getElementById('example1'));
 ReactDOM.render(ele2 , document.getElementById('example2'));
 </script>
</body>

  

通过上面的代码,我们知道在 react ,底层是通过 createElement 方法来创建的虚拟DOM节点,但是我们也可以看出,如果通过这种方式来描述我们的视图,整个人都崩溃了,所以在 react 提供了 JSX 的方式来描述视图。JSX 本质上是 createElement 方法的一个语法糖。

react 中的组件

在 react 中,组件可以分为两大类:

  • 函数式组件(以前被称之为无状态组件)

  • 类组件(以前被称之为有状态组件)

1.在 react 中,创建一个函数式组件非常简单,首先组件名首字母大写、第二个就是要返回一段 JSX

示例如下:

<script type="text/babel">
  function Test(){
    return (
      <h1>Hello</h1>
    )
  }

ReactDOM.render(<Test />, document.getElementById('app'));
</script>

 2.类组件

<script type="text/babel">
  class Test extends React.Component{
    render(){
      return (
        <p>this is a test</p>
      )
    }
  }

ReactDOM.render(<Test />, document.getElementById('app'));
</script>

 3.组件嵌套

<script type="text/babel">
  class HelloReact extends React.Component {
    render() {
      return <h1>hello React</h1>
    }
  }

class HelloJSX extends React.Component {
  render() {
    return <h1>hello JSX</h1>
  }
}

class Welcome extends React.Component {
  render() {
    return (
      <div>
      <HelloReact />
      <HelloJSX />
      </div>
    )
  }
}
ReactDOM.render(<Welcome/>, document.getElementById("app"));
</script>  
传递参数

在 vue 中,父组件向子组件传递参数,使用的是 props,在 react 中,仍然是使用的 props

<script type="text/babel">
//类组件接收参数
  class HelloReact extends React.Component {
    constructor(props){
      super(props)
    }
    render() {
      return (
        <div>
              <h1>hello React</h1>
              <p>{this.props.name}</p>
              <p>{this.props.gender}</p>
              </div>
      )
		}
}
//函数式组件接收参数
function HelloJSX(props){
  return (
    <div>
    <h1>hello JSX</h1>
    <p>{props.name}</p>
<p>{props.gender}</p>
</div>
)
}

//父组件传参
class Welcome extends React.Component {
  render() {
    return (
      <div>
      <HelloReact name="F71" gender="female"/>
      <HelloJSX name="F72" gender="male"/>
      </div>
    )
  }
}
ReactDOM.render(<Welcome/>, document.getElementById("app"));
</script>

  

默认 props

在 vue 中,子组件可以对父组件传递的数据设置一个默认值。react 中也可以。

<script type="text/babel">
  // 类组件
        class HelloReact extends React.Component {
            constructor(props){
                super(props)
            }
       //类组件默认值写在类组件内static defaultProps
            static defaultProps = {
                name : 'ccc',
                gender : 'ddd'
            }

            render() {
                return (
                    <div>
                        <h1>hello React</h1>
                        <p>{this.props.name}</p>
                        <p>{this.props.gender}</p>
                    </div>
                )
            }
        }
  //函数式组件
        function HelloJSX(props){
            return (
                <div>
                    <h1>hello JSX</h1>
                    <p>{props.name}</p>
                    <p>{props.gender}</p>
                </div>
            )
        }
        // 函数组件设置 props 默认值 组件外
        HelloJSX.defaultProps = {
            name : 'aaa',
            gender : 'bbb'
        }

 //父组件
        class Welcome extends React.Component {
            render() {
                return (
                    <div>
                        <HelloReact name="F71"/>
                        <HelloJSX name="F72"/>
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome/>, document.getElementById("app"));
      </script>

  

插槽

<script type="text/babel">
        class Welcome extends React.Component {
            render() {
                return (
                    <div>
                       <p>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
       ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));
 </script>

  

事件的处理

  • 如何绑定事件

  • this 指向的问题

  • 传递参数

事件绑定

<script type="text/babel">
//1.类组件事件绑定
        // class Welcome extends React.Component {
        //     eventHandle(){
        //         console.log('这是一个事件测试!!');
        //     }
        //     render() {
        //         return (
        //             <div>
        //                <p onClick={this.eventHandle}>这是 welcome 组件</p>
        //                {this.props.children}
        //             </div>
        //         )
        //     }
        // }

//2.函数式组件绑定事件
        function Welcome(){
            function eventHandle(){
                console.log('函数组件绑定事件');
            }
            return (
                <p onClick={eventHandle}>this is a test</p>
            )
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));
      </script>

 this 指向问题主要是在类组件里面存在

class Welcome extends React.Component {
            eventHandle(){
                // 我们在组件的事件处理函数上面,期望 this 是指向当前这个组件
                console.log(this);  //underfind
            }
            render() {
                return (
                    <div>
                       <p onClick={this.eventHandle}>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

  类组件里面正常访问 this 时,不能指向当前的组件,拿到的是 undefined

接下来介绍 3 种方式来修正这个 this。

将事件处理函数修改为箭头函数

class Welcome extends React.Component {
            eventHandle = ()=>{
                // 我们在组件的事件处理函数上面,期望 this 是指向当前这个组件
                console.log(this);  //Welcome组件
            }
            render() {
                return (
                    <div>
                       <p onClick={this.eventHandle}>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

2.在 constructor 中通过 bind 来绑定 this 的指向

class Welcome extends React.Component {
            constructor(){
                super();
                this.eventHandle = this.eventHandle.bind(this)
            }
            eventHandle(){
                // 我们在组件的事件处理函数上面,期望 this 是指向当前这个组件
                console.log(this);
            }
            render() {
                return (
                    <div>
                       <p onClick={this.eventHandle}>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

3.在绑定事件的时候,通过箭头函数

class Welcome extends React.Component {
            eventHandle(){
                // 我们在组件的事件处理函数上面,期望 this 是指向当前这个组件
                console.log(this);
            }
            render() {
                return (
                    <div>
                       <p onClick={()=>this.eventHandle()}>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

  事件传参

1.通过 bind 方法,在绑定 this 指向时来传递参数

class Welcome extends React.Component {
            eventHandle=(name,e)=>{
                console.log(this);
                console.log(name);
console.log(e) } render() { return ( <div> <p onClick={this.eventHandle.bind(this,'F71')}>这是 welcome 组件</p> {this.props.children} </div> ) } } ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

 2.通过箭头函数来传递参数

class Welcome extends React.Component {
            eventHandle(name,e){
                console.log(this);
                console.log(name);
                console.log(e);
            }
            render() {
                return (
                    <div>
                       <p onClick={(e)=>this.eventHandle('F71',e)}>这是 welcome 组件</p>
                       {this.props.children}
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome>this is a test</Welcome>, document.getElementById("app"));

  state

state 翻译成中文,是“状态”的意思。也就是说,是组件的状态。

这里的所谓状态,就是指的是组件内部的数据。

class Welcome extends React.Component {
            constructor(){
                super();
                this.state = {
                    name : 'F71',
                    age : 18,
                    gender : 'male'
                }
            }
            render() {
                return (
                    <div>
                      <p>{this.state.name}</p>
                      <p>{this.state.age}</p>
                      <p>{this.state.gender}</p>
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome></Welcome>, document.getElementById("app"));

  在 react 中,为 state 提供了一种简写的形式:

class Welcome extends React.Component {
            state = {
                name : 'F71',
                age : 18,
                gender : 'male'
            }
            render() {
                return (
                    <div>
                      <p>{this.state.name}</p>
                      <p>{this.state.age}</p>
                      <p>{this.state.gender}</p>
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome></Welcome>, document.getElementById("app"));

  react 修改组件的数据,需要调用一个方法。setState 方法,示例如下:

class Welcome extends React.Component {
            state = {
                name : 'F71',
                age : 18,
                gender : 'male'
            }
       //修改数据
            eventHandle = ()=>{
                // 调用setState用新值替换旧的值
                this.setState({
                    age : ++this.state.age
                })
            }
            render() {
                return (
                    <div>
                      <p>{this.state.name}</p>
                      <p>{this.state.age}</p>
                      <p>{this.state.gender}</p>
                      <button onClick={this.eventHandle}>年龄增加</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome></Welcome>, document.getElementById("app"));

  

setState 修改数据的时候,仍然是异步的进行修改。示例如下:

class Welcome extends React.Component {
            state = {
                name : 'F71',
                age : 18,
                gender : 'male'
            }
            eventHandle = ()=>{
                // 用新值替换旧的值
                this.setState({
                    age : 20 //虚拟值
                },function(){
                    console.log(this.state.age); //回调完成后虚拟值赋值给真实值
                })
                console.log(this.state.age); //真实值
                
                
            }
            render() {
                return (
                    <div>
                      <p>{this.state.name}</p>
                      <p>{this.state.age}</p>
                      <p>{this.state.gender}</p>
                      <button onClick={this.eventHandle}>年龄增加</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Welcome></Welcome>, document.getElementById("app"));

  获取state 修改后的值,可以在 setState 中使用回调函数

条件渲染&&列表渲染

条件渲染示例如下:

<script type="text/babel">
        function Com1() {
            return <h1>这是组件1</h1>
        }
        function Com2() {
            return <h1>这是组件2</h1>
        }
        class Com extends React.Component {
            constructor(){
                super();
            }
            state = {
                whichCom: true
            }
            changeCom = () => {
                this.setState({
                    whichCom: !this.state.whichCom
                },)
            }
            render() {
                let com = null;
                if(this.state.whichCom){
                    com = <Com1/>
                } else {
                    com = <Com2/>
                }
                return (
                    <div>
                        <button onClick={this.changeCom}>切换组件</button>
                        <div>{com}</div>
                    </div>
                )

            }
        }
        ReactDOM.render(<Com></Com>, document.getElementById("app"));
    </script>

  列表渲染,示例如下:

<script type="text/babel">
        function Com1() {
            return <h1>这是组件1</h1>
        }
        function Com2() {
            return <h1>这是组件2</h1>
        }
        class Com extends React.Component {
            state = {
                stus : ['唐克超','唐鑫','孙鹏']
            }
            render() {
                let lis = this.state.stus.map((i,idx)=>{
                    return (<li key={idx}>{i}</li>)
                })
                return (
                    <ul>
                        {lis}
                    </ul>
                )

            }
        }
        ReactDOM.render(<Com></Com>, document.getElementById("app"));
    </script>

 

注意:1.JSX中可以使用JavaScript表达式,写在{}中

   2.JSX中不能使用if else语句,但可以使用conditional(三目运算符)表达式替代

   3.React推荐使用内联样式

//方式一
<body>
 <div id="example"></div>
 <script type="text/babel">
 const myStyle = {
 fontSize : 44,
 color : 'blue'
 };
 ReactDOM.render(
 <h1 style = {myStyle}>this is a test</h1>,
 document.getElementById('example')
 );
 </script>
</body>

//方式二
<body>
 <div id="example"></div>

 <script type="text/babel">
 ReactDOM.render(
 <h1 style = {{color :'red'}}>this is a test</h1>,
 document.getElementById('example')
 );
 </script>
</body>

  

   4.JSX给标签设置class需要替换为xlassName,for也要用htmlFor代替

           5.注释  {/* 内容 */}

   6.JSX允许在面板中插入数组,数组会自动展开所有成员

     7.JSX是一种javascript的语法扩展,在React中推荐使用JSX来描述用户界面

   8.在JSX中,根元素只能有一个,如果出现多个根元素,React将不能正常渲染

   

 

 

posted @ 2021-02-23 17:23  瓜豆のO泡  阅读(326)  评论(0)    收藏  举报