React学习小记

  这段时间公司需要用到react+python来进行web开发,这不,上两个礼拜一直在学react和python相关知识,做出了一个小的demo-在线多人聊天室。对上面两种技术从无到有的理解,在做的过程中,也遇到了许许多多问题。虽然感觉基本入门了,但是感觉仍然需要来回顾一遍基础,这样能够更好的掌握。

这篇博文主要是个人对网上知识以及书上知识的总结。

什么是React?

  • React 是一个用于构建用户界面的 JAVASCRIPT 库。
  • React主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)
  • React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
  • React 拥有较高的性能,代码逻辑非常简单

其实到这里,可能对React的理解,就是一个js库嘛,根jquery一样都是个js库嘛,其实不然。
下面看react的特点吧:

  • 声明式设计 −React采用声明范式,可以轻松描述应用。
  • 高效 −React通过对DOM的模拟,即React操作的是一个虚拟DOM,而不是真实DOM,最大限度地减少与DOM的交互。
  • 灵活 −React可以与已知的库或框架很好地配合。
  • JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  • 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  • 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

看了上面的特点,就感觉和jquery不同了吧,jquery更向一个工具包,而React才是一个真正的框架。
在React里面,你可以封装组件,然后这个组件就是一个component,你可以把这个component像html标签一样的使用。后面会讲关于这个component。
另外一个特点就是jsx,jsx可以看作javascript的扩展,里面可以随意嵌套html语言。
由于是组件式的思维,所以当你一个component数据变化时候,需要重新渲染的,也只是你这个component,而不会牵扯到其他component。

如何开始使用React

一、在线直接引用:

<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js">script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js">script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js">script>

二、通过npm安装
npm是nodejs里面一个工具,其实npm就像Java里面的maven,或者python里面的pip,专门用来管理引用包的。

国内使用 npm 速度很慢,你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ npm config set registry https://registry.npm.taobao.org

然后:

$ cnpm install [name]

然后在js里面这样引入:

import React, { Component } from 'react';

就可以在js使用React了。

ReactDOM.render()方法

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
另外,每个component里面都会有一个render方法,这个方法就是用来渲染这个组件的,每当组件state改变时候,就会触发这个方法。
例如这个很简单的例子:

<div id="example">div>
<script type="text/babel">
  ReactDOM.render(
    <h1>Hello, world!h1>,
    document.getElementById('example')
  );
script>

React JSX

  • jsx是一种扩展的js文件,里面可以包括js代码,也可以嵌入html代码。
  • JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。
  • JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员

上面是jsx的基本特性,下面则是一些具体用法注意事项:
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代
例如:

ReactDOM.render(
    <div>
      

{i == 1 ? 'True!' : 'False'}

div>, document.getElementById('example') );

注释需要写在花括号中,实例如下:

ReactDOM.render(
    

anLA的博客

{/*注释...*/}
, document.getElementById('example') );

React渲染html组件和React组件方式:
要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。

var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));

要渲染 React 组件,只需创建一个大写字母开头的本地变量。

var MyComponent = React.createClass({/*...*/});
var myElement = ;
ReactDOM.render(myElement, document.getElementById('example'));

React State(状态)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态(也就是改变当前component的state的值),然后由于render方法里面有引用state的值,所以会自动调用render方法,进而渲染 UI,让用户界面和数据保持一致。这样以来,不需要程序员自己去操作DOM

React Props

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
props的基本用法:

var HelloMessage = React.createClass({
  render: function() {
    return 

Hello {this.props.name}

; } }); ReactDOM.render( "Runoob" />, document.getElementById('example')

我们知道,html标签有属性,例如img标签的src属性,a标签的href属性等,同样在React自定义组件里面,也有属性,在render方法之外,我们可以通过this.props.name 来获得。
props属性的验证:
另外,我们也可以利用propTypes来对props进行验证,当react检测到验证不通过时候,就会在console中报错:

var title = "anLA的博客";
var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

  render: function() {
     return 

{this.props.title}

; } }); ReactDOM.render( , document.getElementById('example') );

当然不同需求的验证还有很多,这里就不一一列出来了。

props和state之间传递数据:
什么意思呢?先看一个简单例子:

var WebSite = React.createClass({
  getInitialState: function() {
    return {
      name: "anLA的CSDN博客",
      site: "http://blog.csdn.net/anla_"
    };
  },

  render: function() {
    return (
      
this.state.name} /> this.state.site} />
); } }); var Name = React.createClass({ render: function() { return (

{this.props.name}

); } }); var Link = React.createClass({ render: function() { return ( this.props.site}> {this.props.site} ); } }); ReactDOM.render( , document.getElementById('example') );

对于Name和Link这两个组件来说,WebSite是他们的父组件,这个时候,按照编程习惯,都是在父组件里面传值,所以就定义了state的两个值,anLA的博客以及http://blog.csdn.net/anla_
这个时候呢,当然子组件得拿的到这两个值,所以在子组件中利用this.props.site 来获取值.
我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。

React组件API

React组件分不同的类别主要有以下几种API:

  • 设置状态:setState(object nextState[, function callback])
  • 替换状态:replaceState(object nextState[, function callback])
  • 设置属性:setProps(object nextProps[, function callback])
  • 替换属性:replaceProps(object nextProps[, function callback])
  • 强制更新:forceUpdate([function callback])
  • 获取DOM节点:DOMElement findDOMNode()
  • 判断组件挂载状态:bool isMounted()

几个注意的地方:
关于setState

  • 不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
  • setState()并不会立即改变this.state,而是创建一个即将处理的state。 - setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
  • setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。
  • replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。

关于props:
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。

关于forceUpdate:
forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.propsthis.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.propsthis.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。

React组件的声明周期

按照被加载的的过程来分,React主要包括以下几个声明周期:

  • componentWillMount() :在渲染前调用,在客户端也在服务端。
  • componentDidMount() : 在第一次渲染后调用,只在客户端。之后组 件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。
  • componentWillReceiveProps(newProps): 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。
  • shouldComponentUpdate(newProps,newState): 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
  • componentWillUpdate(nextProps,nextState):在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
  • componentDidUpdate(prevProps,prevState): 在组件完成更新后立即调用。在初始化时不会被调用。
  • componentWillUnmount():在组件从 DOM 中移除的时候立刻被调用。

    React与表单事件

    在下例总,设置了输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state,即重新渲染一遍。可以使用 onChange 事件来监听 input 的变化,并修改 state。
    前面已经讲过,父组件的state状态,可以通过共享给子组件,方法就是子组件通过this.props.name去获取,这里可以获取变量也可以获取函数。

var HelloMessage = React.createClass({
  getInitialState: function() {
    return {value: 'Hello Runoob!'};
  },
  handleChange: function(event) {
    this.setState({value: event.target.value});
  },
  render: function() {
    var value = this.state.value;
    return 
"text" value={value} onChange={this.handleChange} />

{value}

; } }); ReactDOM.render( , document.getElementById('example') );

React Refs获取真实DOM

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。当然你的组件要新加一个ref属性。
例如下面例子:

var MyComponent = React.createClass({
  handleClick: function() {
    // 使用原生的 DOM API 获取焦点
    this.refs.myInput.focus();
  },
  render: function() {
    //  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
      
"text" ref="myInput" /> "button" value="点我输入框获取焦点" onClick={this.handleClick} />
); } }); ReactDOM.render( , document.getElementById('example') );

最后,还有几点需要注意的地方:

  • 组件类的第一个字母必须大写,否则会报错,比如HelloMessage不能写成helloMessage。
  • 组件类只能包含一个顶层标签,否则也会报错。
  • this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点
  • 组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

参考资料:
https://reactjs.org/
React教程-菜鸟教程
React入门实例教程

你可能感兴趣的:(前端)