React 基础知识

react 有手机 app 扩展库 --ReactNative 使用原生 JS 开发手机 app


React 开发分两种方式 1.脚本方式 2.脚手架方式

脚本方式

  1. 引入 react.js脚本
  2. React提供两个类
    React:负责创建元素
    ReactDOM:负责渲染元素,其他的元素中
  3. 利用 React 创建元素
    例:let h3 = React.createElement( "h3" ,{ id:"time", className:"time"}, "当前时间:10:12" )
  4. 利用 ReactDOM 渲染到"id=root"标签中
    React.render(h3,"root")

学习JSX

  1. JSX:在 js 中书写 xml格式的DOM 操作代码; html 是 xml 中的一种,即标签语言
  2. JSX属于特殊语法,浏览器不认识,浏览器无法识别,因此需要 引入babel 工具进行翻译,并且在 script 标签上加 type="text/babel",代表此脚本必须 使用babel 编译
  3. 例:
// 把当前时间展示到 id="root" 的标签中

let tiem = "10:56"
let h3 = <h3 className="danger" id="time">当前时间:{ time }<h3>
ReactDOM.render(h3,root);

注意:vue,angular,小程序中差值表达式为 {{ js 代码 }},而 JSX 中为 { js 代码 }

学习组件

  1. 组件:组成页面的零件
  2. 组件的特征:复用性
  3. React 采用 函数 和 类 制作组件
    1)函数:适合简单组件制作
    2) 类:适合复杂组件制作
  4. 组件函数名要求大坨峰写法:更容易区分组件和普通函数
  5. 例:

函数方式

function HelloWord () {
  return <h1>hello word!</h1>;
};
ReactDOM.render(HelloWord (),root);
// 语法糖写法,babel自动编译成 HelloWord()
ReactDOM.render(<HelloWord/>,root);
// render() :非新增操作而是会覆盖
// 复用性:
let more = (<div>
    <HelloWord/>
    <HelloWord/>
    <HelloWord/>
</div>)
ReactDOM.render(more,root);

类方式
1)类方式制作组件:创建具有强大能力的组件要求必须继承父类

class HelloWord extends  React.component {
    render(){
        return <h1>Hello Word!</h1>
    }
}
// 使用
React.render(new HelloWord().render(),root);
// 语法糖写法
React.render(<HelloWord/>,root);
// 复用行
let more = (<div>
     <HelloWord/>
     <HelloWord/>
     <HelloWord/>
</div>)
React.render(more,root);

父子传参
1)函数组件传参

function HelloWord (props) {
  return <h1>hello,{props.name}</h1>
};
React.render(HelloWord( {name:"中国"} ),root);
// 语法糖
React.render(<HelloWord name="中国"/>,root);

2)类组件传参
this.props 来自于父类的constructor 方法,该方法 new 时自动触发

class HelloStar extends React.component {
    // 带有 this 前缀说明props 是成员属性,成员属性可以跨方法使用
    // constructor(props) {
    //      this.props = props;
    // }
    render() {
        return <h1>hello,{this.props.star}</h1>
    }
}
ReactDOM.render(new HelloStar({name:"林俊杰"}),render(),root);
// 语法糖
ReactDOM.render(<HelloStar name="林俊杰"/>,root);

事件

  1. 用户可以通过操作 UI触发各种事件,如点击事件、失焦事件等
  2. 函数书写建议使用箭头函数不会出现 this 指向问题
class Demo extends React.component {
    name = "俊杰"
    show = () =>{
        console.log(this.name)
    }
    render() {
        // 事件的绑定 
        // vue 中 v-on:click="方法名",简写@click="方法名"
        // React 中 onClick="方法名"
        // React 中 {}中的方法会直接执行 ,所以方法是否加()是有区别的,加会直接执行,不加事件触发执行
        return (
            <div>
                <button onClick={this.show}>点击触发~</button>
                <button onClick={this.show()}>点击触发~</button>
            </div>
        )
    }
}

状态值

  1. React中,使用state存储数据,通过{ }显示在页面上,利用 setState( )更新数据,可以让 UI 同步刷新
  2. state状态值只有使用类组件才能使用
  3. vue 中只要修改数据页面就会更新,React 中必须使用 state 和 setState 配合
  4. state 中的数据必须使用 setState 页面才会刷新页面,setState 会做两件事 修改数据+修改 UI
class Demo extends React.component {
   state = {
        count:1
   }
   _addCount = ()=>{
       // setState是异步操作,方法第二个参数是回调函数,在数据渲染成功时触发
       this.setState({count:this.state.count + 1},()=>{
           console.log("回调函数",this.state.count);  
       })
   }
   // 类中的方法有很多,通常分为两种
   // 1)事件绑定 2)普通方法
   // 约定与事件绑定的方法带前缀 _ 
   render(){
       return (
          <div>
              <h3>{this.state.count}</h3>
              <butten onClick={this._addCount}>点击+1</butten>
          </div>
       )
   }
}
ReactDOM.render(<Demo/>,root);

安装脚手架

  1. 脚手架是一个工具,可以快速搭建项目的基本架构完成所需资源的下载和配置
  2. 脚手架安装要求 node >=8.10 &&npm >= 5.6 查看当前版本 node -v && npm -v
  3. React 脚手架安装命令: npm i -g create-react-app,创建项目命令: create-react-app 项目名
  4. 创建的项目名不允许有大写字母
  5. 安装官方插件,rcc 生成项目基本结构,vscode 不识别 JSX 语言,切换语言为JavaScript React才会有代码提示


    image.png
  6. 项目的启动流程
    1)项目下执行 npm start 命令会开启一个服务器,服务器程序唯一标识 端口号:3000
    2)浏览器上访问localhost:3000
    3)webpack工具:脚手架自动配置了此工具,项目运行时会自动打包index.js引入到 index.html 中
    4)index.js 引入了 App.js并且渲染到 id="root" 的标签上
    5)App.js 项目的根组件
  7. React项目是 SPA 项目:Single web Page Application,即单网页应用,只有一个页面,通过路由切换局部内容,实现页面变更

条件渲染

  1. React 的条件渲染不同于 Vue ,需要单独写一个函数并在渲染出调用
  2. 为什么调用时 没有 this 指向问题?此方法不是事件触发而是刷新时触发,this 指向不是 window
  3. 判断条件一定是 state相关的值,setState 更新时就会自动刷新更新 UI
show() {
  if(this.state.num == 0) return <h1>000</h1>
  if(this.state.num == 1) return <h1>111</h1>
}
render() {
  return (
      <div>当前号码</div>
      {this.show()}
  )
}

列表渲染

  1. React 中的列表渲染需要单独写一个方法去改造数组,实现数组里放 JSX 语法渲染
  2. 循环数组的每项都需要带一个唯一标识 key
  3. 使用数组的 map 方法会更简单的实现列表渲染
arr = [11,22,33,44]
arrFn () {
    let arr2 = [];
    this.arr.forEach((item,index) =>{
        arr2.push(<div key={index}>{item}</div>)
    });
    return arr2;
}
// 使用数组的 map 方法
arrMapFn () {
    return this.arr.map((item,index)=>{  
            return <div key={index}>{item}</div>
        }
    )
}
render () {
    return (
        <div>{this.arrFn()}</div>
    )
}

动态风格样式

  1. 即在页面展示时 样式能动态的发生变化
  2. JSX语法中样式需要写成对象类型
  3. 样式分为两种写法___ 1)内联式 style ___2)外部样式 css文件+class
    1)内联式
//点击按钮使文字变大
state={
   size:18
}
render() {
   return (
       <div style={{fontSize: this.state.size + "px"}}>Hello</div>
       <button onClick={() => this.setState({size : this.state.size + 2})}>点击变大</button>
   )
}

2)外部样式

// App.css
.style1 {
    background-color: #fff;
}
.style2 {
    background-color: #000;
}
.style3 {
    background-color: #999;
}

// App.js
import "./App.css";

state={ size:18 }
styleFn() {
    let num = this.state.size;
    if(num == 20) return "style1"
    if(num == 22) return "style2"
    if(num == 24) return "style3"
}
render () {
    return (
        <div className={this.styleFn()}>hello</div>
        <button onClick={() => this.setState({size : this.state.size + 2})}>点击变大</button>
    )
}

双向数据绑定

  1. from表单中的元素,通常能够与用户交互,此时会出现数据绑定到 UI 元素,UI 元素因为用户操作发生变化,同步更新到数据的情况,即为双向数据绑定
  2. 用户更改 UI 会触发 onChange方法,使用 onChange方法实现UI 变化时数据同步
  3. 事件触发的方法,会带 event 事件对象参数
  4. 事件默认是 Dom 事件,但在 React 中对 Dom 事件进行了处理,处理之后的事件叫做 同步事件
  5. 同步事件:把值传入后会自动销毁自身,要想打印事件中的值必须调用event.persist(),对读值没有影响,且不是实时的值
state={
    uname: "",
    upwd: ""
}
_changeN=(event)=>{
   // event.persist()
   // console.log(event)
   this.setState({uname:event.target.value})
}
_changeP=(event)=>{
   // event.persist()
   // console.log(event)
   this.setState({upwd:event.target.value})
}
render(){
    return (
        <input/ type="text" placeholder="用户名" value={this.state.uname} onChange={this._changeN}>
        <input/ type="password" placeholder="密码" onChange={this._changeP}>
        <button>登录</button>
    )
}

生命周期

  1. 组件生成、更新、销毁的过程
  2. 组件的每个关键过程都会有钩子函数被触发
  3. componentDidMount钩子函数会在被挂载时触发,通常在这个钩子函数中发送请求,获取数据
  4. componentWillUnmount钩子函数会在组件被销毁时触发,通常在这个钩子函数中销毁一些资源防止内存泄漏,例如定时器
  5. componentDidUpdate钩子函数会在组件更新时触发,有两个参数props,state
    1)props:属性,接收外来传参,props是旧值,新值是 this.props
    2)state:状态值,组件本身的变化,state 是旧值,新值是 this.state
  6. shouldComponentUpdate钩子函数的两个参数会返回即将变化的值,以此来判断是否更新组件,提高 React 的渲染效率,面试会经常问
import React, { Component } from 'react'

export default class App extends Component {
    state = {
        show: false
    }
    isShow() {
        if(this.state.show) return <Son/>
    }
    render() {
        return (
            <div>
                {this.isShow()}
                <button onClick={()=>this.setState({show:!this.state.show})}>点击</button>
            </div>
        )
    }
}
class Son extends Component {
    componentDidMount() {
        console.log('componentDidMount钩子函数触发,组件挂载');
    };
    componentWillUnmount() {
        console.log('componentWillUnmount钩子函数触发,组件销毁');
    };
    componentDidUpdate(props,state) {
        console.log('旧值', props, '新值', this.props)
        console.log('旧值',state,'新值',this.state)
    };
    shouldComponentUpdate(props, state) {
        // props,state 代表即将变化的值,即即将展示的值
        if (state.count % 2) {
            // false 代表组件不会刷新到页面上,则 didupdate 函数也不会触发
            return false
        } else {
            return true
        };
    };
    render() {
        return (
            <div>我是子组件</div>
        )
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349