React实战开发工作原理

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. 用户访问 View
2. View 发出用户的 Action
3. 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标签的形式呈现给用户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值