zoukankan      html  css  js  c++  java
  • reactJs 基础

    react不是一个完整的mvc,mvvm框架。

    react跟web components 不冲突  背景原理:基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新

    react的特点就是‘轻’

    组件化的开发思路

    应用场景:复杂场景下的高性能  重用组件库,组件组合

    ReactDOM.render()是React最基本方法 ,用于将模版转为HTML语言,并插入指定的DOM节点。

    React.createClass()方法 就用于生成一个组件类  每个组件类都必须有自己的 render: 方法,用于输出组件。

                                       注意:1 组件类第一个字母大写  2 组件类只能包含一个顶层标签 如用<div> 包裹

                     <HelloMessage name="John"> 组建的属性可以在 组件类的 this.props 对象上获取,this.props.name可以获取到

    this.props.children 表示此组件的所有子节点  三种结果:1 没有子节点 undefined 2 有一个子节点 object   3 有多个子节点 array

    React.Children.map() 遍历子节点

    组件类的PropTypes 属性,用来验证组件实例的属性是否符合要求 

            propTypes:{title:React.PropTypes.string.isRequired,}

    getDefaultProps 方法用来设置组件属性的默认值  getDefaultProps:function(){return{title:'Hello World'};}

    ref属性  可以从组件中获取真实DOM节点   父组件引用子组件

        this.refs.[name] 返回真实的DOM节点 需要等到click事件后调用

    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} />
    ) 
    }
    })    
    

    组件中getInitialState 方法用于定义初始化状态(对象),可以通过this.state属性读取。

     

    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>
        );
      }
    });

    this.setState方法就修改状态值,每次修改后 自动调用this.render 方法,再次渲染组件。

    this.props 表示那些一旦定义 就不再改变的特性;

    this.state 是会随着用户互动而产生改变的

    上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况

     

    引入解析jsx的文件  <script src='http://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js'></script>  type=''text/javascript"

    reactComponent 是指创建的dom节点

     

    react component lifecycle的生命周期:

    1 Mounted --- React.renderComponent()    React Components被render解析生成对应的DOM节点 并被插入浏览器的DOM结构的一个过程

     componentWillMount 前被调用 --> render --> componentDidMount  后被调用

     getDefaultProps()   

    getInitialState() 初始化

    2 Update --- setState() / setProps() 至render()   一个mounted的ReactComponents被重新render的过程

      componentWillUpdate / componentDidUpdate   / shouldComponentUpdate /componentWillReceiveProps

    3 Unmounted --- React.unmountAndReleaseReactRootNode()  一个mounted的React Components对应的DOM节点 被从DOM结构中移除的这样一个过程

      componentWillUnmount

    总结:每一个状态 react都封装了对应的hock函数

     

    组件的生命周期:初始化——运行中——销毁

    初始化:可使用的钩子

    1  getDefaultProps  只调用一次,实例之间共享引用

    2 getInitialState  初始化每个实例特有的状态,都需要调用

    3  componentWillMount  render之前最后一次修改状态

    4 render  只能访问this.props和this.state  不允许修改状态和DOM输出

    5 componentDidMount  渲染完成之后触发,可对dom进行操作。

    运行中:

    1 componentWillReceiveProps 父组件修改属性触发,可以修改新属性,修改状态

    2 shouldComponentUpdate  返回faulse 会阻止render调用

    3 componentWillUpdate  不能修改属性和状态

    4 render 只能访问this.props 和 this.state,不允许修改状态和DOM输出

    5 componentDidUpdate 可以修改DOM

    销毁:

    componentWillUnmount

    属性 组件自己不能修改属性,可以从父组件获取属性,父组件也可以修改它的属性,他也可以修改子组件的属性 :本身具有的,属性的四种用方式:

    1  <HelloWorld name=? />  出入键值对  "字符创"  “item”

     2 {“time”}{123}数字、字符串、等  var props={one:'123',two:321} <HeeloWorld{...props}/>   {...props}展开对象的方式,取到的是值;{props}此方法取到的是对象

    3 {【1,2,3】}数组

    4 {变量}

    状态 只和自己相关 与父组件子组件都不相关,有自己维护 :事物所处的状况,不断变化的

    状态用法:

    1 getInitialState:初始化每个实例特有的状态

    2  setState:更新组件状态

    setState-----diff-----dom

    区分:组件在运行中需要修改的数据就是 状态。

     

    极客react 

    非dom节点:

    1、 dangerouslySetInnerHTML = {rawHTML}

    var rawHTML = {__html:"<h1>i'm inner HTML"}
    React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,  )
    

    2、ref  

    3、key  列表类相同的节点 li 一定要加上key值 <li key='1'></li><li key='2'></li>

    事件用法:组件(1,React自有方法:render  、componentWillUpdate、componentDidMount

                           2. 用户定义方法:handleClick、handleChange、handleMouseover)

    绑定事件处理函数:

    触摸:onTouchCancel

    onTouchEnd

    onTouchMove

    onTouchStart

    键盘:onKeyDown

    onKeyPress

    onKeyUp

    剪切:onCopy

    onCut

    onPaste

    表单:onChange

    onInput

    onSubmit

    焦点:onFocus

    onBlur

    UI元素:onScroll

    滚动:onWheel

    鼠标:onDrop/onDrag/onDragEnd/onDragEnter/onDragExit/onDragLeave/onDragOver/onDragStart

    onClick/onContextMenu/onDoubleClick/onMouseDown/onMouseEnter/onMouseLeave/onMouseLeave/onMouseMove/onMouseOut/onMouseOver/onMouseUp

    事件对象的属性:

    事件和状态关联:

    handleChange:function(e){this.setState({inputText:e.target.value})}

    组件协同:

    1 组件嵌套: 父子关系  父组件-属性-》子组件;子组件-委托(触发事件)-》父组件

    2 mixin:React双向绑定Minxin

    组件要可控:符合react的数据流;数据存储在state中,便于使用;

    表单元素:

    <label htmlFor="name">对应相应的input的id</label>

    <input><textarea><select><option></option></select>

    事件处理函数复用:

    1、bind复用:

        handleChange:function(name,event){....}

      {this.handleChange.bind(this,'input')}

    2、name复用:

      handleChange:function(event){var name=event.target.name}

      {this.handleChange}

    React性能调优:

    提高性能的方式:虚拟DOM,diff算法,将dom操作减少到最小,但是

            问题1:父组件更新默认出发所有子组件更新;解决方法:子组件覆盖shouldComponentUpdate方法,返回true,触发更新流程,生成新的虚拟DOM节点与之前的进行比较,不同则进行操作;返回false,自行解决是否更新。

            问题2:列表类型的组件默认更新方式比较复杂;解决方法:给列表中的组件添加key属性

    性能调优:分析性能热点

    控制台输入React.addons.Perf.start()--->进行一次操作---->React.addons.Perf.stop()  ;完成后台记录消耗时间

          查看记录结果:React.addons.Perf.printInclusive();

    如何解决性能问题:1;PureRenderMixin判断是否需要进入更新流程,本质上就是判断状态和属性是否改变(只能处理原始值,不能处理对象)

      在shouldComponentUpdate(nextProps,nextStates)内判断!shallowEqual(this.props,nextProps)||!shallowEqual(this.state,nextState);

    2;不可变插件Immutability Helpers,实现js不可变对象

      基本语法:update(obj,cmd)

    组件嵌套:

     钩子函数:

    初始化:getDefaultProps  只调用一次

    getInitialState

    componentWillMount  渲染之前最后一次修改状态this.setState({}),触发render()函数;

    render

    componentDidMount  操作或修改真正的dom

    运行中:componentWillReceiveProps  父组件修改属性之前触发,此函数可以修改新属性、修改状态

    shouldComponentUpdate  返回false,根据需要使用

    componentWillUpdate :不能修改属性和状态

    render:只能访问this.props和this.state,不能修改

    componentDidUpdate :可以修改dom

    销毁:componentwillUnmount  在删除组件之前进行清理操作,比如计时器和事件监听器,必须手动清理。方法1.在子组件中componentwillUnmount:function(){}  方法2:在子组件的handle函数中,调用:React.unmountComponentAtNode(document.getElementsByTagName('body')[0]);//传入的必须是装载入的节点。

    React.findDOMNode()

    react添加css动画:

    var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; 引入react-addons-t

    调用:return(<ReactCSSTransitionGroup transitionName="example">{items}</ReactCSSTransitionGroup>)

    react添加js动画:

    componentDidUpdate:function(){if(this.props.position){setTimeout(this.resolveSetTimeout,this.props.timeoutMs);}},

    render:function(){var divStyle={marginLeft:this.state.position};return <div style={divStyle}>this will animate!</div>}})

    React.render(<Positioner></positioner>,document.body);

    React.render(<Positioner position={100} timeout={10}></Positioner>,document.body);第二次调用,改变属性值props,触发componentDIdUpdate();从而达到动画效果

    项目实战:

     1.分析目标-确定开发顺序:页面上有组件->组件能正常显示内容->内容的样式正确->设置项可以正常工作->交互功能正常

    在jsx中使用循环,一般会用到Array.prototype.map

    class Hello extends React.Component{
          render(){
             const arr = ['a','b','c'];
             return (
               <div>
                 {arr.map((item,index) => {
           return <p key={index}> this is {item}</p>  
    })}
        </div>
        )
        }
    }        

    参考链接:http://www.imooc.com/article/14500

    代码分离

    page层  ./app/containers/Hello/index.jsx

    subpage层  ./app/containers/Hello/subpage/...jsx

    component层  ./app/components/...  把多个页面都可能用到的功能,封装到一个组件中,放到此目录下。

    数据传递&数据变化

    props:一般只用作父组件给子组件传递数据用,不能被自身修改。

    每个页面引用Header时,设置独自的title属性值,<Header title='Hello页面'/>;而在子组件中这样取到 render(){return(<p>{this.props.title}</p>)}  

    state:自身组件状态发生变化,constructor(props,context){super(props,context);this.state = {now:Date.now()}}  render(){return (<div><p>hello world {this.state.now}</p></div>)}}

    智能组件&木偶组件

    智能组件:./app/containers   简称“页面”,只对数据负责,只需获取数据、定义好数据操作的相关函数,然后将这些数据、函数直接传递给具体的实现组件。

    木偶组件:做一些展示的工作,展示给用户。 ./app/components/...

    性能检测优化:参考https://github.com/wangfupeng1988/react-simple-o2o-demo/tree/getready-redux-width-react   本地切换到对应的分支

    1安装react的性能检测工具npm install react-addons-perf --save  在./app/index.jsx中import Perf from 'react-addons-perf'   if(__DEV__){window.Perf = Perf}

    使用:Perf.start()开始检测,Perf.stop停止检测,Perf.printWasted()即可打印出浪费性能的组件列表。

    2安装react的优化插件 PureRenderMixin,npm install react-addons-pure-render-mixin --save

    使用:在constructor(props,context){super(props,context);this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);}}  重写组件shouldComponentUpdate函数,在每次更新之前判断props和state,如果有变化返回true。

    3 Immutable.js优化:使用此来处理数据,实现js中不可变数据的概念。适用于数据结构层次很深(obj.x.y.a.b=10)其定义了新的语法,不轻易使用。

    React-router

    安装 npm install react-route --save

    1 创建子页面./app/containers/App.jsx 所有页面的外壳 ./app/containers/Home等主页、列表页、详情页

    2 配置router 创建./app/router/routerMap.jsx 文件

    class RouteMap extends React.Component{
        updateHandle(){
            //每次router变化之后都会触发
       }
        render(){
            return (
                <Router history={this.props.history}  onUpdate={this.updateHandle.bind(this)}>
                    <Route path='./'  component={App}>
                            <IndexRoute component={Home}/>
                            <Route path='list' component={list}/>
                            <Route path='detail/:id'  component={Detail}/>     //id表示参数
                            <Route path="*" component={NotFound}/>
                    </Route>                                                  //route可以嵌套
                </Route>
            )
        }
    }

    3 使用Route

    ./app/index.jsx

    import React from 'react'
    import {render} from 'react-dom'
    import {hashHistory} from 'react-router'
    
    import RouteMap from './router/routeMap'
    
    render(
        <RouteMap history={hashHistory}/>,         //hashHistory规定hash来表示router localhost:8080/#/list
        document.getElementById('root')
    )

    页面跳转

    1 <link to='/list'>to list </link>

    2 js跳转

    return(<ul>

          {arr.map((item,index) => {

            return <li key={index} onClick={this.clickHandle.bind(this,item)}>js jump to {item} </li>})}

        </ul>)}

    clickHandle(value){

      hashHistory.push('/detail/' + value)

    }}

    性能优化--静态资源懒加载  huge-apps 

    他将react-router本身和webpack的require.ensure结合起来,解决此问题。

  • 相关阅读:
    zabbix邮件报警设置(加密)
    Linux实战(10):ssh密码被拒绝
    Linux实战(9):Docker一键搭建kms服务
    Linux实战(8):查看文件大小
    Linux实战(7):centos7安装xrdp
    Linux实战(6):Centos8上传镜像
    Linux实战(5):Centos8安装python
    Linux实战(4):Centos7升级python
    nginx实战(1):宝塔设置反向代理
    Dell服务器R710修改iDRAC密码
  • 原文地址:https://www.cnblogs.com/yxiaoqian/p/5867508.html
Copyright © 2011-2022 走看看