React 语法基本使用介绍

前面的文章我们已经配置好了环境,接下来熟悉一下 react 的基础语法:

一、认识入口文件

React 中,app/main.js 叫做入口文件,这个文件是 webpack.congifg.js 的 entry 标识的文件。任何项目入口文件只能有 1 个。

入口文件写法:

import React from "react";
import ReactDom from "react-dom";
import App from "./App";

ReactDom.render(
    <App />,
    document.querySelector("#app")
);

React 库就是 React 核心库,ReactDOM 库专门用于入口文件,调用ReactDOM.render() 方法 ,负责将根组件上树。

引入React 的作用,是因为 React 使用了 jsx 语法,jsx 语法简单理解就是不加引号的 HTML 语法裸写在 JS 文件里面,jsx 是英语 JavaScript Extension(JavaScript增强版)的意思,自称是世界上将 HTML 和 JS 融合的最好的语言。jsx 语法会被 babel 翻译为字符串拼接。但是,React 规定,一个有 jsx 语法的 js 文件,必须引入 React 包,否则babel 不予翻译。

根组件上树的语法:
ReactDOM.render(JSX , 挂载点);

二、初识组件

组件(component):将页面中的一部分区域的 HTML 结构、CSS 样式、交互效果、数据等进行封装,封装到独立的一个文件中开发,叫做组件。

React 中组件是类,定义一个继承 React.Component 类的类,就是一个组件。
React 规定,所有的组件都是一个类,首字母必须严格大写。

在 app 文件夹中创建 App.js,然后书写标准的类的“壳子”:

import React,{Component} from "react";
export default class App extends Component {
    // 构造函数
    constructor(){
        //必须调用超类(父类)
        super();
    }
    render(){
        return (
            <div>
                <h1>我是 App.js 根组件,早上好!</h1>
            </div>
        );
    }
}

类的名字尽可能和文件的名字一样。

官方手册上对 render 函数的描述:The render method returns a description of what you want to see on the screen. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write.
翻译:render函数返回了你想要在屏幕上呈现的东西。一般来说,render 函数要 return一个 React 元素,这个元素描述了组件长什么样子。绝大部分 React 的开发者,使用了一个叫做 JSX 的语法让结构更易于书写。

return 后面直接跟的是 jsx 语法,没有任何的引号的 HTML。注意不能在 return 后面换行的,因为换行就默认 return undefined 了。如果你非要换行必须像我一样在上面加个圆括号在圆括号里面换行。

定义完一个类之后,其他的 js 文件就能够引入它,然后使用它的名字当做标签名,从而使用实例化这个类:
import App from "./App";

所以使用组件非常简单:① 引包 ② 变成标签对 或 单标签
每当我们写了一个组件的标签对之后,就相当于实例化了一次。

三、JSX 语法

JSX 是 facebook 公司为了 React 专门打造的语言,并且已经申请了专利,JSX 确实好用。JSX = JavaScript Extension,也有说法叫做 JavaScript + XML。

专门解决 JavaScript 和 HTML 结合的问题。因为我们原来经常写:

"<div>我爱你" + year + "年</div>"

JSX 彻底解决了这个问题。

<div>我爱你{year}年</div>

  • JSX 要求标签严格封闭,尤其是单标签,单标签必须写末尾反斜杠,比如:
//img 的路径以 index.html 文件为准
<img />
<br />

必须这么写,要不然报大错。

  • 表格标签必须添加 tbody 标签。

  • class 要避讳为变为 className,因为 class 在 JS 里面是关键字。

  • JS 生命之源,单大括号插值语法

可插入语法

  1. JS简单的计算 <h1>我爱你{5000 * 2}年</h1>
  2. JS 内置的函数 <h1>我爱你{parseInt(10000.6)}年</h1>
  3. 插入变量 const year = 10000;<h1>我爱你{year}年</h1>
    注意,变量可以存储 JSX 语法:
    const a = <span>我爱你<em className="spec">10000</em>年</span>;
  4. 插入函数的执行{sum()} 和 允许插入IIFE。
  5. 插入三元运算符
    <h1>我爱你{3 > 8 ? 9 : 10000}年</h1>
  6. 插入自定义组件{<App><App/>}

不可插入语法

  1. 不能插入 for 循环
  2. 不能插入if语句
  3. 不能插入while语句
  4. 不能插入函数的声明
  5. 不能插入对象
  • src 动态属性值
    基本使用请记住 "大包引" ,大括号包住引号。

var star = 0 ;<img src = {`images/${star}.png`} />

  • 行内样式
    口诀:双大括号,标准JSON,省略 px,属性驼峰。
    注意:即使不需要将style属性变动态,也需要写成这样,这是规定。
<p style={{
    "width" : 200,
    "height" : 200,
    "backgroundColor" : "red"
}}></p>
  • 动态类名
    我们需要安装一个依赖:

npm install --save classnames

靠布尔值来决定这个类名是否生效:

<p className={classnames({
                    "cur" : true,
                    "pure" : true,
                    "color" : 3 > 8,
                    "red" : 0
                })}>你好</p>
  • JSX 中使用数组(很关键,同时也是难点、重点)

注意: JSX的单大括号中如果出现数组,数组会被自动展开。

var arr = ["点绛唇·梅","宋代:朱翌","流水泠泠,断桥横路梅枝亚。","雪花飞下,浑似江南画。","白璧青钱,欲买春无价。","归来也,风吹平野,一点香随马。"];
//================
<ul>
    {arr.map((item,index)=> <li key={index}>{item}</li>)}
</ul>

React 中,JSX 数组项,每项都必须有独一无二的 key 属性。key 简单来说,react 利用 key 来识别组件,它是一种身份标识标识,就像我们的身份证用来辨识一个人一样。每个 key 对应一个组件,相同的 key react 认为是同一个组件,这样后续相同的 key 对应组件都不会被创建. react 中的 key 属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置 key 之后不能获取组件的这个key props),而是给 react 自己用的。
key的使用场景?基本基本就是数组。
官方:在项目开发中,key 属性的使用场景最多的还是由数组动态创建的子组件的情况,需要为每个子组件添加唯一的 key 属性值。
注意:index 作为 key 是一种反模式。
在数组中生成的每项都要有 key 属性,并且 key 的值是一个永久且唯一的值,即稳定唯一。key 值的唯一是有范围的,即在数组生成的同级同类型的组件上要保持唯一,而不是所有组件的 key 都要保持唯一。
了解更多参考博客:React 之 key详解https://segmentfault.com/a/1190000009149186

对数组操作用到的最多的两个 ES 方法,就是上面 Map 和 filter。俗称:删 filter 改 Map 。

四、九九乘法表
九九乘法表
render(){
    var arr = [];
    for(let i = 1;i <= 9; i++){
        let temp = [];
        for(let j = 1;j <= i;j++){
            temp.push(<td style={{border:"1px solid #353"}} key = {j}>{i} X {j} = {i*j}</td>)
        }
        arr.push(<tr key = {i}>{temp}</tr>);
    }
    return(
            <div>
                <table style={{
                    borderCollapse:"collapse"
                }}>
                    <tbody>
                        {arr}
                    </tbody>
                </table>
            </div>
        );
}
五、组件的 state、事件监听和 MVVM 模式

我们可以快速感知 React ,从一个小小的计数器开始一步步熟悉。


计数器.gif
import React,{Component} from "react";

export default class App extends Component{
    constructor(){
        super();
        this.state = {
            a : 0
        }
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {()=>{
                    this.setState({
                        a : this.state.a + 1
                    })
                }}>按我加一</button>
                
                <button onClick = {()=>{
                    this.setState({
                        a : this.state.a - 2
                    })
                }}>按我减二</button>
            </div>
            )
    }
}

代码分析:

  • 组件的 state
    React 规定,任何实例允许有 state 属性,表示这个组件实例的数据。注意,construtor中 this 表示什么?表示实例,即 state 属性是组件的实例的属性。
    注意 state 必须是 state 属性,不能改名,state 属性的值必须是对象,不能是字符串、不能是数组等。在render中,可以使用单大括号,这样的写法,显示出state。
  • setState()
    箭头函数中要改变 state 对象的 a 属性值,此时必须用 setState 函数进行修改。React 规定,只有用 setState 来改变 state 界面才能自动更新;千万注意不能直接用 ++,-- 等一元运算符。
  • 事件监听
    在 2008 年,人们认识到了 HTML、CSS、JS 三层分离。所以我们原生 JS、jQuery 都分离的厉害,很明显现在我们让他们耦合在了一起。
    onClick={},这个 {} 中要放一个函数。注意这个函数必须是箭头函数,不能是 function。
六、变体写法

事件监听直接写在标签里面是在是太乱了,可以把事件提取出来,需要注意的是提取出来的事件需要绑定上下文的 this 。

    add(){
        this.setState({
            a : this.state.a + 10
        })
    }
    unadd(){
        this.setState({
            a : this.state.a - 10
        })
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {this.add.bind(this)}>按我加十</button>
                <button onClick = {this.unadd.bind(this)}>按我减十</button>
            </div>
            )
    }

这种写法简洁了,但是不能传参数,所以可以利用箭头函数的特性来规避这个问题。

import React,{Component} from "react";

export default class App extends Component{
    constructor(){
        super();
        this.state = {
            a : 0
        }
    }
    add(n){
        this.setState({
            a : this.state.a + n
        })
    }
    unadd(m){
        this.setState({
            a : this.state.a - m
        })
    }
    render(){
        return (
            <div>
                <h1>{this.state.a}</h1>
                <button onClick = {()=>{
                    this.add(100);
                }}>按我加一百</button>
                <button onClick = {()=>{
                    this.unadd(100);
                }}>按我减一百</button>
            </div>
            )
    }
}
传参.gif
七、如何获取 DOM

无论是 Vue 还是 React 都是数据驱动视图,因此官方都不建议使用 DOM 操作,但是还是预留了这个 API 那就是 ref。2019-7-31 号的时候即之前的 React还是和 Vue 一样操作 DOM 基本相同都是使用 String 类型的 Refs 例如:<h1 ref="textInput "></h1> ,你可以通过 this.refs.textInput 来访问 DOM 节点。但现在 React 不建议使用它了,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除。

存在 一些问题

现在官网建议用:

  • 回调函数
  • createRef

需要注意的是节点的引用可以在 ref 的 current 属性中被访问(三点):

  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
  • 你不能在函数组件上使用 ref 属性,因为他们没有实例

上面讲了函数没有实例,那怎么使用 ref 呢。答案是使用 forwardRef 方法。

const refA  = createRef();
function A(props,ref){
    return (
        <div>
            <h1 ref={ref}>i am A</h1>
        </div>
    )
}
A = forwardRef(A);
ReactDOM.render(<div>
    <A ref={refA}></A>
    <button onClick = {()=>{
        console.log(refA.current);//h1标签
    }}>点击</button>
</div>, document.getElementById("root"));

forwardRef 会使 A 函数多出来一个参数 ref ,不使用 forwardRef 方法,函数是没有第二个参数的。从效果来看 forwardRef 方法就是把函数变成类。refA.current 返回的是 h1 标签,我们还可以使用 useImperativeHandle 改写使其返回一个对象,注意⚠️ 16.6.3 版本这个方法叫做 useImperativeMethods 。

function A(props, ref) {
    const inputRef = useRef();
    useImperativeHandle(ref, () => ({
      focus: () => {
        inputRef.current.focus();
      },
      name:"Condor Hero",
      age:19
    }));
    return <input ref={inputRef} />;
}
A = forwardRef(A);

const refA  = createRef();
ReactDOM.render(<div>
    <h4>
        <A ref={refA}></A>
        <button onClick = {()=>{
            console.log(refA.current.name);
            console.log(refA.current);
        }}>点击</button>
    </h4>
</div>, document.getElementById("root"));
八、MVVM 思想

简单一句话,数据变化,视图自动变化。实现起来就是使用事件来操作 setState 让 其内部的值发生改变,视图自动更新。

来两个案例体验一下。第一个调色板:

双向数据绑定,简称双向绑定,再简称双绑。在 React 中也称为“受控”(under controlled)。

说一下 ref,在 React 中,任何元素都可以添加 ref 属性,表示 reference 引用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,005评论 0 1
  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,221评论 0 9
  • 1、什么是react React.js 是一个帮助你构建页面 UI 的库。React.js 将帮助我们将界面分成了...
    谷子多阅读 2,555评论 1 13
  • 最近看了一本关于学习方法论的书,强调了记笔记和坚持的重要性。这几天也刚好在学习React,所以我打算每天坚持一篇R...
    gaoer1938阅读 1,670评论 0 5
  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,806评论 0 24