React实战开发工作原理

来源:互联网 发布:域名授权系统 编辑:程序博客网 时间:2024/05/22 05:31

React工作原理:
把每一个组件当成了一个状态机,组件内部通过state来维护组件状态的变化,当组件的状态发生变化时,React通过虚拟DOM技术来增量并且高效的更新真实DOM。
虚拟DOM则是在DOM的基础上建立了一个抽象层,我们对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到DOM中。

React 特点:
1.声明式设计 −React采用声明范式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
首次渲染大量DOM时因为多了一层虚拟DOM的计算,会比innerHTML插入方式慢。
props 主要作用是提供数据来源,可以简单的理解为 props 就是构造函数的参数。可以通过this.props来访问props
把每一个组件都看成是一个状态机,组件内部通过state来维护组件状态的变化,这也是state唯一的作用。
JSX 做的事情就是根据 state 和 props 中的值,结合一些视图层面的逻辑,输出对应的 DOM 结构。

React JSX

  • 关于React注释的问题:

1、在标签内部的注释需要花括号
2、在标签外的的注释不能使用花括号

ReactDOM.render(    /*注释 */    <h1>孙朝阳 {/*注释*/}</h1>,    document.getElementById('example'));
  • 使用 JavaScript 表达式,表达式写在花括号 {} 中:
ReactDOM.render(    <div>      <h1>{1+1}</h1>    </div>    document.getElementById('example'));
  • 在 JSX 中不能使用 if else 语句,但可以使用三元运算 表达式来替代。代码中嵌套多个 HTML 标签,需要使用一个标签元素包裹它,即组件类只能包含一个顶层标签。
    React 推荐使用内联样式。我们可以使用驼峰命名法来设置内联样式。React 会在指定元素数字后自动添加 px 。
 var myStyle = {    fontSize: 100,    color: '#FF0000'};ReactDOM.render(    <h1 style = {myStyle}>菜鸟教程</h1>,    document.getElementById('example'));
  • HTML标签vs React组件

    React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。 要渲染 HTML 标签,只需在JSX 里使用小写字母的标签名。

var myDivElement = <div className="foo" />;ReactDOM.render(myDivElement,document.getElementById('example'));要渲染 React 组件,只需创建一个大写字母开头的本地变量。var MyComponent = React.createClass({/*...*/});var myElement = <MyComponent someProperty={true} />;ReactDOM.render(myElement,document.getElementById('example'));

React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
注意:
由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

React组件
接下来封装一个输出”Hello World!”的组件,组件名为HelloMessage。

var HelloMessage = React.createClass({render: function() {return <h1>Hello World!</h1>;//return <h1>Hello  {this.props.name}</h1>; } }); ReactDOM.render(<HelloMessage  />,//<HelloMessage name= “陈陈陈陈小妖” />,document.getElementById('example'));

React.createClass 方法用于生成一个组件类 HelloMessage。
实例组件类并输出信息。
如果我们需要向组件传递参数,可以使用 this.props 对象。 (↑修改)
注意,原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签(需要使用一个标签元素包裹其它标签),否则也会报错。

同时,我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。

var WebSite = React.createClass({render: function() {return (<div><Name name={this.props.name} /><Link site={this.props.site} /></div>);}});var Name = React.createClass({render: function() {return (<h1>{this.props.name}</h1>); }});var Link = React.createClass({render: function() {return (<a href={this.props.site}> {this.props.site} </a>); }});ReactDOM.render(<WebSite name="陈陈陈陈小妖" site=" http://www.baidu.com"; />, document.getElementById('example'));注意:组件名不一定是用单标签,也可以是双标签<HelloMessage /> == <HelloMessage></HelloMessage>React State(状态)React 把组件看成是一个状态机,通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。以下实例中创建了 LikeButton 组件,getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。var LikeButton = React.createClass({        getInitialState: function() {          return {liked: false};      //getInitialState是用来初始化state        },        handleClick: function(event) {  //handleClick是用来处理点击事件          this.setState({liked: !this.state.liked});        },        render: function() {          var text = this.state.liked ? '喜欢' : '不喜欢';          return (             <p onClick={this.handleClick}>                你<b>{text}</b>我。点我切换状态。             </p>          );        }      });      ReactDOM.render(        <LikeButton />,        document.getElementById('example')      );

onClick 等事件,与原生 HTML 不同,on 之后第一个字母是大写的!比如本章实例中,如果将 onClick={this.handleClick} 换成 onclick ={this.handleClick} 则点击事件不再生效。

React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
可以通过 getDefaultProps() 方法为 props 设置默认值
Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。

React 组件 API
设置状态:setState
setState(object nextState[, function callback])

* nextState,将要设置的新状态,该状态会和当前的state合并* callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。

替换状态:replaceState
replaceState(object nextState[, function callback])

* nextState,将要设置的新状态,该状态会替换当前的state。* callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。
设置属性:setProps
替换属性:replaceProps
replaceProps()方法与setProps类似,但它会删除原有
强制更新:forceUpdate
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
获取DOM节点:findDOMNode

* 返回值:DOM元素DOMElement

如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。
判断组件挂载状态:isMounted

* 返回值:true或false,表示组件是否已挂载到DOM中

isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

React生命周期:

  • Mounting:已插入真实 DOM
    这里写图片描述
  • Updating:正在被重新渲染
    这里写图片描述
  • Unmounting:已移出真实 DOM
    这里写图片描述

React AJAX:
React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。

这里写图片描述
这是一个React组件实现组件可交互所需的流程,render()输出虚拟DOM,虚拟DOM转为DOM,再在DOM上注册事件,事件触发setState()修改数据,在每次调用setState方法时,React会自动执行render方法来更新虚拟DOM,如果组件已经被渲染,那么还会更新到DOM中去。
每个组件都有属于自己的state,state和props的区别在于前者之只存在于组件内部,只能从当前组件调用this.setState修改state值(不可以直接修改this.state)。一般我们更新子组件都是通过改变state值,更新新子组件的props值从而达到更新。

父子组件沟通
这种方式是最常见的,也是最简单的。

* 父组件更新组件状态

父组件更新子组件状态,通过传递props,就可以了。

* 子组件更新父组件状态

这种情况需要父组件传递回调函数给子组件,子组件调用触发即可。

兄弟组件沟通

当两个组件有相同的父组件时,就称为兄弟组件(堂兄也算的)。按照React单向数据流方式,我们需要借助父组件进行传递,通过父组件回调函数改变兄弟组件的props。

Flux 是什么?
Flux 是一种架构思想,专门解决软件的结构问题。它跟MVC 架构是同一类东西,但是更加简单和清晰。
首先,Flux将一个应用分成四个部分。
View: 视图层
Action(动作):视图层发出的消息(比如mouseClick)
Dispatcher(派发器):用来接收Actions、执行回调函数
Store(数据层):用来存放应用的状态,一旦发生变动,就提醒Views要更新页面

这里写图片描述

Flux 的最大特点,就是数据的”单向流动”。

1. 用户访问 View2. View 发出用户的 Action3. Dispatcher 收到 Action,要求 Store 进行相应的更新4. Store 更新后,发出一个"change"事件5. View 收到"change"事件后,更新页面

Redux Redux 只是 Web 架构的一种解决方案
这里写图片描述

首先,用户发出 Action。
store.dispatch(action);
然后,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action。 Reducer 会返回新的 State 。
let nextState = todoApp(previousState, action);
State 一旦有变化,Store 就会调用监听函数。
// 设置监听函数
store.subscribe(listener);
listener可以通过store.getState()得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。

React-router
React-router的BrowserRouter(重命名为Router),Route,Link三个组件。新版本的react-router提出了一切都以Component实现的原则,因此这些组件实际上都是React.Component的实现。
BrowserRouter是一个容器Component(组件),其内部实现了路由跳转的逻辑。
Route也是一个Component(组件),配置了页面路径以及当用户输入的路径命中时需要渲染的组件。
Link用于跳转,有点像HTML的a标签。不一样的是Link是需要在后端进行编译,最终可能以a标签的形式呈现给用户。

原创粉丝点击