前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React全家桶简介

React全家桶简介

作者头像
LIYI
发布2019-09-02 15:41:52
2K0
发布2019-09-02 15:41:52
举报
文章被收录于专栏:艺述论专栏

当前前端开发已经进入以vue、react、webpack为代表的编程2.0时代。在1.0时代,代码是写给机器的;在2.0时代,代码是写给工具的,然后由工具处理后再转给机器。

一、React全家桶简介

JSX语法糖

使用React,不一定非要使用JSX语法,可以使用原生的JS进行开发。但是React作者强烈建议我们使用JSX,因为JSX在定义类似HTML这种树形结构时,十分的简单明了。这里简单的讲下JSX的由来。

比如,下面一个div元素,我们用HTML语法描述为:

代码语言:javascript
复制
<div class="test">
 <span>Test</span>
</div>

如果换做使用javascript描述这个元素呢:

代码语言:javascript
复制
{
 type:"div",
 props:{
   className:"test",
   children:{
     type:"span",
     props:{
       children:"Test"
     }
   }
 }
}

这样我们就可以在javascript中创建一个Virtual DOM(虚拟DOM)了。当然,这样是没法复用的,我们再把它封装一下:

const Div=>({text}){ return { type:"div", props:{ className:"test", children:{ type:"span", props:{ children: text, }, }, }, } }

接下来再实现这个div就可以直接调用Div('Test')来创建。但上述结构看起来实在让人不爽,写起来也很容易写混,一旦结构复杂了,很容易让人找不着北,于是JSX语法应运而生。我们用写HTML的方式写这段代码,再经过翻译器转换成javascript后交给浏览器执行。

上述代码用JSX重写:

代码语言:javascript
复制
const Div =()=>(
 <div className="test">
 <span>Test</span>
 </div>
);

所谓语法糖,就是借助工具将复杂工作由人工转为机器完成。小程序中的WXS,也可以看作是一种语法糖,但是一种尚未成熟的语法糖。ES6的箭头函数在JS中也是语法糖,Bable可以将它自动转化为同等的ES5语法。

Virtual DOM

虚拟DOM的概念并不是FB首创却在FB的手上大火了起来。

在Html中对DOM进行更新操作十分昂贵,为减少对于真实DOM的操作,诞生了Virtual DOM的概念,也就是用javascript把真实的DOM树描述了一遍,使用的也就是我们刚刚说过的JSX语法。对比如下:

每次数据更新之后,重新计算Virtual DOM,并和上一次的Virtual DOM对比,对发生的变化进行批量更新。(注:React也提供了shouldComponentUpdate生命周期回调,来减少数据变化后不必要的Virtual DOM对比过程。)

Virtual DOM虽然渲染比传统的DOM操作要好一些,但对比DOM节点也是需要计算的,最大的好处在于可以很方便的和其它平台集成,比如react-native就是基于Virtual DOM渲染出原生控件。具体渲染出的是Web DOM还是Android控件或是iOS控件就由平台决定了。

React-router

应用程序的路由。它通过管理 URL,实现组件的切换和状态的变化。对应于vue-router。

安装

代码语言:javascript
复制
npm install -S react-router

使用,可以将路由器Router看作React的一个组件

代码语言:javascript
复制
import { Router } from 'react-router';
render(<Router/>, document.getElementById('app'));

Router组件本身只是一个容器,真正的路由要通过Route组件定义。使用JXS语法。

代码语言:javascript
复制
import { Router, Route, hashHistory } from 'react-router';
render((
 <Router history={hashHistory}>
   <Route path="/" component={App}/>
 </Router>), document.getElementById('app')
);

上面代码中,用户访问根路由/(比如http://www.example.com/),组件APP就会加载到document.getElementById('app')。

Redux

从角色功能上讲,相当于vuex。主要包括三个主要概念:State、action、reducer。

Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。

Redux 默认并不包含 React 绑定库,可能需要单独安装。

代码语言:javascript
复制
npm install --save react-redux

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化。Redux就是为了解决这个复杂场景而设计的。

可以把React的model看作是一个个的子民,每一个子民都有自己的一个状态,所有model统一由Redux统一管理。

组件分两种,容器组件和展示组件。

Store

Store 是Redux中的主要概念,是保存数据的地方,它实际上是一个Object tree。整个应用只能有一个 Store。

Store主要职责:

  • 维持应用的 state;
  • 提供 getState() 方法获取 state;
  • 提供 dispatch(action) 方法更新 state;
  • 通过 subscribe(listener) 注册监听器;
  • 通过 subscribe(listener) 返回的函数注销监听器。
action

State 的变化,会导致 View 的变化。Action 就是 View 发出的通知,表示 State 应该要发生变化了。即store的数据变化来自于用户操作。一般来说,View会通过 store.dispatch() 将 action 传到 store。

Action 是一个对象。其中的type属性是必须的,表示 Action 的名称

代码语言:javascript
复制
const action = {  
 type: 'ADD_TODO',  
 payload: 'Learn Redux'
};
reducer

Action 只是描述了有事情发生了这一事实,并没有指明应用如何更新 state。而这正是 reducer 要做的事情。

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。

代码语言:javascript
复制
const reducer = function (state, action) {  
  // ...
 return new_state;
};

单向数据流

与vue一样,react的数据流动也是单向的。

Redux 应用中数据的生命周期遵循下面 4 个步骤:

  • 调用 store.dispatch(action)。
  • Redux store 调用传入的 reducer 函数。
  • 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。
  • Redux store 保存了根 reducer 返回的完整 state 树。
Connect

React-Redux 提供connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。

代码语言:javascript
复制
import { connect } from 'react-redux';
const TodoList = connect()(Memos);

上面代码中Memos是个UI组件,TodoList就是由 React-Redux 通过connect方法自动生成的容器组件。完整的connect方法这样使用:

代码语言:javascript
复制
import { connect } from 'react-redux'
const TodoList = connect(
 mapStateToProps
)(Memos)

上面代码中,connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

Provider

这个Provider 其实是一个中间件,它是为了解决让容器组件拿到state对象而存在的。

代码语言:javascript
复制
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
let store = createStore(todoApp);
render(  
 <Provider store={store}>
   <App />
</Provider>,  
 document.getElementById('root')
)

上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。

这个设计非常符合在React中“一切皆组件”的设计思想。

react-router

安装

npm install --save react-router-dom

React UI库

知名的库有:Ant Design,Material UI

二、React使用简介

获取原始DOM节点

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性

var MyComponent = React.createClass({ handleClick: function() { this.refs.myTextInput.focus(); }, render: function() { return ( <div> <input type="text" ref="myTextInput" /> <input type="button" value="Focus the text input" onClick={this.handleClick} /> </div> ); } });

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后this.refs.[refName]就会返回这个真实的 DOM 节点。

需要注意的是,由于this.refs.[refName]属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取this.refs.[refName]属性。

this.state

组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI。

var LikeButton = React.createClass({ getInitialState: function() { return {liked: false}; }, handleClick: function(event) { this.setState({liked: !this.state.liked}); }, render: function() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> You {text} this. Click to toggle. </p> ); } }); ReactDOM.render( <LikeButton />, document.getElementById('example') );

上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

由于 this.props 和 this.state 都用于描述组件的特性,这两个概念可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

关于表单的值

用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取。

var Input = React.createClass({ getInitialState: function() { return {value: 'Hello!'}; }, handleChange: function(event) { this.setState({value: event.target.value}); }, render: function () { var value = this.state.value; return ( <div> <input type="text" value={value} onChange={this.handleChange} /> <p>{value}</p> </div> ); } }); ReactDOM.render(<Input/>, document.body);

上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。

关于组件的生命周期

组件的生命周期分成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

  • componentWillMount()
  • componentDidMount()
  • componentWillUpdate(object nextProps, object nextState)
  • componentDidUpdate(object prevProps, object prevState)
  • componentWillUnmount()

这五个函数的全名与OC类库的命名风格颇为类似。

此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

Ajax

组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI。

componentDidMount: function() { $.get(this.props.source, function(result) { var lastGist = result[0]; if (this.isMounted()) { this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); } }.bind(this)); },

上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。React 本身没有任何依赖,完全可以不用jQuery,而使用其他库。

等等。


参考资料:

  1. https://juejin.im/post/587b52d8570c352201fd993d
  2. http://www.ruanyifeng.com/blog/2016/05/react_router.html
  3. https://blog.csdn.net/stwuyiyu/article/details/86140697
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JSX语法糖
  • Virtual DOM
  • React-router
  • Redux
    • action
      • reducer
        • Connect
          • Provider
          • React UI库
          • 获取原始DOM节点
          • this.state
          • Ajax
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档