React.js

菜鸟官方解释:

React 是一个用于构建用户界面的 JAVASCRIPT 库。

React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。

React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。

React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它

React特点:

  • 1.声明式设计 −React采用声明范式,可以轻松描述应用。

  • 2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。

  • 3.灵活 −React可以与已知的库或框架很好地配合。

  • 4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。

  • 5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

  • 6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

Virtual Dom

  • state创建数据

  • jsx 模板

  • 数据 + 模板 生成Virtual DOM(虚拟节点就是js创建的一个对象,该对象是对节点的一个描述,包含了该节点的所有信息,attrs,content等)

  • 用虚拟DOM生成真实的DOM,显示

  • state改变

  • 数据 + 模板生成新的 Virtual DOM

  • 对比新旧Virtual DOM的区别,找到区别。

  • 直接操作DOM改变有区别的地方。

    注:因为浏览器在解析网页时,js和html是分开的。就相当于两个模块,js要跨越界限操作别人的东西,所以说代价是比较大的。虚拟dom的创建使得性能很大程度提升,且他的应用 使得跨端应用得意实现 React Native.在android和ios端是不存在dom一说的,所以在创建虚拟dom后,会将虚拟dom生成对应的原生的东西。

Progressive Web Application

字义即:渐进式Web应用

PWA有可以实现什么呢?

  • 可以将app的快捷方式放置到桌面上,全屏运行,与原生app无异

  • 能够在各种网络环境下使用,包括网络差和断网条件下,不会显示undefind

  • 推送消息的能力

  • 其本质是一个网页,没有原生app的各种启动条件,快速响应用户指令

    在React.js中。public文件夹下有一个mainfest.json的文件夹,该文件就是用来实现桌面快捷方式的配置,而无网络情况,或网络情况较差时,则使用service worker来实现离线缓存。

Service Worker

Web离线引用解决方案。指在在进过网页后,当网络断开连接后,依然可以再次访问页面。

ServiceWorker的主要能力集中在网络代理和离线缓存上。具体的实现上,可以理解为ServiceWorker是一个能在网页关闭时仍然运行的WebWorker

在通过react脚手架创建项目后,src根目录下是有一个serviceWorker.js文件的,该文件就是用来写app时,提供离线缓存技术。供线下仍可正常访问。

Immutable

保证state中的数据不被修改。修改数据时,不能通过this.state.xx来就该数据需要用特定的方法this.setState({});可以发现和小程序也是一样的了

JSX

百度解释:

JSX是一种JavaScript的语法扩展,运用于React架构中,其格式比较像是模版语言,但事实上完全是在JavaScript内部实现的。元素是构成React应用的最小单位,JSX就是用来声明React当中的元素,React使用JSX来描述用户界面。

详细使用:JSX

 render() {
return (
<div>
<ul>
<li></li>
</ul>
</div>
)
}

上面代码等同于下面

 render() {
return React.createElement('div',{},React.createElement('ul',{},React.craeteElement('li',{})));
}

他的顺序:jsx => createElement => Virtual Dom => 真实Dom

vue和react的虚拟节点的渲染其实是一致的

className

在设置样式时,我们原来都是通过添加class或者id来设置对应的类名,在react中因为创建模板时使用的就是class类,所以在渲染模板时,样式的设置可以通过className=""来设置

Fragment

每个组件都要求有大的标签包裹,但是会产生不必要的DOM,因此react提供了Fragment来坐占位符。这样就不会产生新的节点,且组件不会抱任何错误。

 import React, { Component,Fragment } form 'react';

class Demo extends Component {
render() {
return (
<Fragment>
Html content
</Fragment>
)
}
}

dangerouslySetInnerHTML

在render中如果要使某些内容不被转义。

则我们就需要使用dangerouslySetInnerHTML来保持元素不被转义

 <div dangerouslySetInnerHTML={{ __html: '<div>123</div>' }} />
  1. dangerouslySetInnerHTMl 是React标签的一个属性,类似于angular的ng-bind;

  2. 有2个{{}},第一{}代表jsx语法开始,第二个是代表dangerouslySetInnerHTML接收的是一个对象键值对;

  3. 既可以插入DOM,又可以插入字符串;

  4. 但是存在一个问题,因为使用标签内容后会将其转换,所以很有可能遭到XSS攻击。

import React,{ Component,Fragment } from 'react';
import './style/todoList.css' class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
list: []
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<Fragment>
{/**这里是注释 */}
<input
className="input"
onChange={this.handleInputChange.bind(this)}
value={this.state.inputValue}
/>
<button className="btn" onClick={this.handleSubmit}>提交</button>
<ul>
{
this.state.list.map((item,index) => {
return (
<li
key={index}
onClick={this.handleDeleteItem.bind(this,index)}
dangerouslySetInnerHTML={{__html:item}}
>
</li>
)
})
}
</ul>
</Fragment>
)
};
handleInputChange(e) {
this.setState({
inputValue: e.target.value
})
};
handleSubmit() {
this.setState({
list: [...this.state.list,this.state.inputValue],
inputValue: ''
})
};
handleDeleteItem(index) {
let list = [...this.state.list];
list.splice(index,1);
this.setState({
list: list
})
}
}
export default TodoList;

当我们在input中输入<h1>Hello World</h1>时,如果使用了dangerouslySetInnerHTML的话,h1标签就会生效。

htmlFor

在使用label时,一般我们会通过for与input上的id进行绑定。在react中,我们则需要通过htmlFor=""来绑定input

组件传值

父传子

父传子通过属性传递,将需要传递的数据放在子组件上,通过属性的方式传递,子组件通过this.props.attr则就可以获取到父组件传递过来的数据

父组件:

import TodoItem from './TodoItem'
render() {
return (
<ul>
{
this.state.list.map((item,index) => {
return (
<div>
<TodoItem content={item} index={index} />
{/*<li
key={index}
onClick={this.handleItemDelete.bind(this,index)}
dangerouslySetInnerHTML={{__html:item}}
>
</li>*/}
</div>
)
})
}
</ul>
)
}

给子组件将数据挂在到content和index上,

子组件的获取

import React, { Component } from "react";

class TodoItem extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
render() {
return (
<div>{this.props.content}</div>
)
}
} export default TodoItem;

通过this.props就可以获取到父组件传递过来的数据。

子传父

子传父的话,没有vue那么多的方法,这里需要在父组件先将方法传递给子组件。

子组件调用父组件更改数据的方法。获取将数据作为方法的参数调用传递给父组件的方法就可以。

将方法通过属性的方式挂在到子组件上,不过需要注意的是,这里需要绑定指向为父组件

还是刚才的内容

import React,{ Component,Fragment } from 'react';
import TodoItem from './TodoItem';
import './style/todoList.css'; class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
list: []
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleItemDelete = this.handleItemDelete.bind(this);
}
render() {
return (
<Fragment>
<div>
<label htmlFor="inputArea">输入内容</label>
<input
id="inputArea"
className="input"
onChange={this.handleInputChange}
value={this.state.inputValue}
/>
<button
className="btn"
onClick={this.handleSubmit}
>提交</button>
</div>
<ul>
{this.getTodoItem()}
</ul>
</Fragment>
)
};
getTodoItem() {
return this.state.list.map((item,index) => {
return (
<TodoItem
key={index}
content={item}
index={index}
deleteItem={this.handleItemDelete}
/>
)
})
}; handleInputChange(e) {
const value = e.target.value;
this.setState(() => ({
inputValue: value
}))
};
handleSubmit() {
this.setState((prevState) => ({
list: [...prevState.list,prevState.inputValue],
inputValue: ''
}))
};
handleItemDelete(index) {
this.setState((prevState) => {
const list = [...prevState.list];
list.splice(index,1);
return {list}
})
}
}
export default TodoList;

deleteItem就是挂在的方法,供子组件调用

子组件

import React, { Component } from "react";

class TodoItem extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
render() {
const { content }= this.props;
return (
<div onClick={this.handleClick}>
{content}
</div>
)
}
handleClick() {
const { deleteItem,index } = this.props;
deleteItem(index);
}
} export default TodoItem;

注:react是单向数据流,举这样一个例子:父组件引用了5个子组件,每个子组件都引用了父组件传递的list.如果不是单向数据流,子组件在对this.props.list= [];做出修改后,其他4个子组件会怎样?

显示这就是一个bug了,修改一个其他的都修改了。显然是一个比较严重的问题。所以react单向数据里就是解决这样一个问题。

父组件传递给子组件的数据,是无法做出修改的。state中的数据有一个只读属性,是无法做出修改的。如果非要修改,需要父组件传递给子组件一个方法,子组件通过调用该方法来实现数据的更改。

setState

该方法用来更新state数据,调用该方法时,就算state中的数据没有做修改,也会重新执行render方法。

setState({
isActive: true,
})
console.log(this.state.isActive)//false

该方法其实是一个异步操作,所以要得到最新的state需要在第二个参数回调函数中获取或者通过async和await来解决啦

async handleClick() {
await this.setState({
isActive: true
})
console.log(this.state.isActive);//true
}

该方法有两个参数

setState((prevState) => {
//prevState是旧的数据
},()=> {
//这里可以得到更新以后的数据
})

PropTypes

组件间传值时,对接受数据的一个限制

详细doc可查看官网https://reactjs.org/docs/typechecking-with-proptypes.html

import { PropTypes } from 'prop-types'
class 组件 extends Component {}
组件.propTypes = {
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
}

isRequired

要求该传值对象不能为空,必须有值

组件.propTypes = {
obj: PropTypes.string.isRequired
}

arrayOf()

要求类型可以为多项

组件.propTypes = {
obj: PropTypes.arrayOf(PropTypes.number,PropTypes.string)
}

defaultProps

为组件间传值的对象设置默认值

 class 组件 extends Component {}
组件.defaultProps = {
obj1: 'hello world'
}

设置默认值后,父组件在未传递数据时,会默认使用该默认值

后续继续学习更新

React.js初探的更多相关文章

  1. React.js初探(一)

    前端框架多如牛毛的今天,团队的技术选型很重要,没有最好的,只有最合适的,这话早已经被说烂了. 但是作为一个有追求的前端,对新技术的敏感以及尝试心理还是要有的. 虽然React已经火的不行了,但由于自己 ...

  2. MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录

    注:文章内容都是摘录性文字,自己阅读的一些笔记,方便日后查看. MVC MVC(Model-View-Controller),M 是指业务模型,V 是指用户界面,C 则是控制器,使用 MVC 的目的是 ...

  3. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

  4. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  5. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

  6. React.js深入学习详细解析

    今天,继续深入学习react.js. 目录: 一.JSX介绍 二.React组件生命周期详解 三.属性.状态的含义和用法 四.React中事件的用法 五.组件的协同使用 六.React中的双向绑定   ...

  7. React.js入门必须知道的那些事

    首先,React.js是facebook在2013年5月开源的一个前端框架,React不是一个MVC框架,它是构建易于可重复调用的web组件,侧重于UI, 也就是view层, React为了更高超的性 ...

  8. React.js 官网入门教程 分离文件 操作无法正常显示HelloWord

    对着React官网的教程练习操作,在做到分离文件练习时,按照官网步骤来却怎么也无法正常显示HelloWord. 经测试,html文件中内容改为: <!DOCTYPE html><ht ...

  9. React.js入门笔记(再续):评论框的实现

    本案例来自React.js中文官网对应内容. 一. 运行环境 <link rel="stylesheet" type="text/css" href=&q ...

随机推荐

  1. jenkins环境搭建(Windows)

    1.下载并解压Tomcat Tomcat官方网站:http://tomcat.apache.org/ 下载并解压,解压后的目录结构如下: 2.下载并安装适合自己电脑系统的 jenkins Jenkin ...

  2. CF176E Archaeology(set用法提示)

    题目大意: 给一棵树,每次激活或熄灭一个点,每次问这些点都联通起来所需的最小总边权 分析: 若根据dfs序给所有点排序,为$v1,v2,v3....vk$,那么答案就是$(dis(v1,v2)+dis ...

  3. @FunctionalInterface

    >> 函数式接口也称为SAM接口 Single Abstract Method interfaces 接口有且仅有一个抽象方法 允许定义静态方法 允许定义默认方法 允许java.lang. ...

  4. 32.修改IK分词器源码来基于mysql热更新词库

    主要知识点, 修改IK分词器源码来基于mysql热更新词库     一.IK增加新词的原因 在第32小节中学习到了直接在es的词库中增加词语,来扩充自已的词库,但是这样做有以下缺点: (1)每次添加完 ...

  5. 24.通过ngram分词机制实现index-time搜索推荐

    一.ngram和index-time搜索推荐原理     1.什么是ngram     假设有一个单词:quick,在5种长度下的ngram情况如下: ngram length=1,q u i c k ...

  6. jQuery学习----简单介绍,基本使用,操作样式,动画

    jQuery简单介绍 jq是js的插件库,说白了,jq就是一个js文件 凡事能用jq实现的,js都能实现.但是js能实现的,jq不一定能够实现 jq的引入 http://www.bootcdn.cn ...

  7. 费用最少的一款赛门铁克SSL证书

    Symantec Secure Site SSL证书,验证域名所有权和企业信息,属于Symantec Class 3企业(OV)验证 级SSL证书,为40位/56位/128/256位自适应加密,目前连 ...

  8. noip模拟赛 hungary

    分析:比较难的一道题,看到要求方案数,又是在一棵树上,自然就想起了树形dp.状态该怎么表示呢?首先肯定有一维状态表示以i为根的子树,考虑到i有没有匹配对答案也是有影响的,自然而然状态就出来了:f[i] ...

  9. CODEVS——T 2969 角谷猜想

    http://codevs.cn/problem/2969/  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descri ...

  10. 洛谷——P2347 砝码称重

    https://www.luogu.org/problem/show?pid=2347#sub 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输 ...