react基础知识快速学习

项目构建

  • git && github
  • nodejs
  • webstrom
  • chrome
  • shell
  • babel es6 plugin preset
  • webpack

跑通项目

  • 使用es6语法和react,需要babe来编译;npm i babel-core babel-loader babel-preset-es2015 babel-preset-react --save-dev
    babel-preset-stage-0 用来解决尖头函数不兼容的问题;
  • index.html作为模版,需下载:html-webpack-plugin

jsx语法

  • 就是js+xml语法的混合;
  • 顶层标签只允许出现一个;
  • 注释的写法:{/这是jsx中的注释/}
  • class需要写为 className
  • label中的for,需要改为htmlFor
  • jsx样式的写法
render(){
    const name="圆梦源123";
    const styles={
        fontSize:'30px',
        color:'red'
    };
    return(
        
{/*这是jsx中的注释*/}

你好,{name}!

) }

react虚拟DOM

  • 什么是虚拟DOM(Virtual DOM)
    虚拟DOM保存了真实DOM的层次关系和一些基本属性,与真实DOM一一对应。虚拟DOM的工作原理是:数据 -> 全新的虚拟DOM -> 与上一个状态的虚拟DOM进行diff算法比较,得到一个Patch -> 把这个Patch打到浏览器的DOM上。所以虚拟DOM叫的挺高端,其实就有点类似DocumentFragment,把多次DOM操作做一个批处理。
  • 什么是diff算法?
    • 现在前端框架比的是算法。diff算法说白了就是比较两个文件不同的算法。
    • 比较前后两个状态虚拟DOM的diff算法,可以简单分为三部分,我总结了三句话
      • 虚拟DOM树同一位置不同类型(标签不同)的节点:删除前一状态节点,插入后一状态节点,哪怕节点有子节点也这样做;
      • 虚拟DOM树同一位置相同类型但个别属性不同的节点,对前一状态节点进行属性重设;
      • 列表节点(就是我们用循环创建的类似Array的节点),如果没有unique key(没有控制台会报警告的)就按照前面两种方式解决,如果有unique key就找到key相应的位置插入节点。
  • 虚拟DOM快在哪里?
    • js计算肯定要比DOM操作快啊,每次DOM操作都很有可能引起回流(Reflow)和重绘(Repaint)啊。当然浏览器也不傻,不是你每次操作DOM浏览器都重绘一次,一般浏览器会按照时间或次数间隔进行DOM操作的批处理。
    • 到底是浏览器优化后的DOM批处理快,还是React的虚拟DOM+优化diff算法快?这个不清楚,根据博客上内容,React的优化更人性化、也更快。速度快肯定是虚拟DOM的一个优点;
    • 主要是主动权不同:浏览器对DOM操作批处理的主动权不在前端人员手中,React将这种批处理的时机选择交到了我们手中,看我们什么时候想render页面。

对react组件添加样式

  • 写在css文件中,通过import导入,给标签className赋值;

react中的属性props

  • 组件定义和导出

  • props 组件间的数据流动

    • 定义参数规则 prop-types模块的运用
    • 默认参数的设置 defaultProps
    //参数规格的设定
    Profile.propTypes={
        url:propTypes.string,
        name:propTypes.string,
        id:propTypes.number.isRequired
    };
    //参数默认值;可传可不传
    Profile.defaultProps={
        name:'leilei'
    };
    
  • state 管理组件自己内部的数据

var MyComponent=function(props){
    var state={

    }
    return "v dom"
}

refs引用DOM元素:range举例

update=(e)=>{
    console.log(findDOMNode(this.refs.one).value)
    this.setState({
        name:e.target.value
    })
}

子组件children属性

  • this.props.children

    • 可以拿到我们传给该组件下的所有的元素;
      比如该组件叫List,我们就能拿到h1和h2
    
        

    12233

    12233

  • React.children

    • forEach
    • map
    //先导入children:  import {Children} from React
    let node=Children.map(this.props.children,(item)=>{
        return 
  • {item}
  • });

react生命周期图

react基础知识快速学习_第1张图片

react-router内容介绍,我们使用3.0.5版本

  • 打通基本开发环境

  • 基于react-router跑通基本路由

    • Router:整个路由相关的配置
    • Route:具体的路由
    • hashHistory:在前端通过路由展现UI
    
        
        
    
    
  • 使用Link组件进行导航切换:类似于a链接

  • 组件和路由的嵌套使用

    • 多个组件的嵌套组合,构成一个路由对应的页面;
    index->App
    page1->App+Contact
    page2->App+About
    
    • 结合this.props.children; 它拿的是当前组件下的子组件;
  • activeClassName和activeStyle设置路由激活状态

    • 当你访问一个路由,通过路由的设置,可以实现页面的跳转;
    • activeClassName - 相当于外链的css样式
    • activeStyle - 相当于行内样式
    • 小实战:封装导航组件
  • params路由参数

    • 路由变量设置和获取
    /concat/footer
    /concat/header
    /concat/:message/:haha
    

    通过{this.props.params.message} {this.props.params.haha} 获取对应的路由参数; 以后传路由,必须按我们提前设置好的规则传递;

  • 更复杂的路由嵌套结合

  • IndexRoute的使用

    • 在解释默认路由(IndexRoute)的用例之前,我们来设想一下,一个不使用默认路由的路由配置是什么样的?
    
        
            
            
        
    
    

    当用户访问/时,App组件被渲染,但组件內的子元素却没有,App内部的this.props.children为undefined,这个时候,我们只可以简单的使用{this.props.children||}来渲染一些默认的UI组件;

    • IndexRoute
    
        
            {/*设置默认路由*/}
            
            
            
        
    
    
  • IndexLink的使用

    首页
    Home
    

    会匹配任何以/开始的子路由,但是,我们访问的/路由,只希望展示Home组件;

  • 路由重定向 Redirect


  • 如何使用browserHistory

    • react-router 是基于history构建的,利用history属性来监听浏览器地址栏的变化,并且,将URL进行解析后放入到location对象中,从而给react-router提供UI和路由之间的匹配;
    • 三种history属性类型
      • hashHistory
        • 不需要你配置服务器即可使用
        • 不支持服务端渲染
        • 不建议在生产环境使用
      • browserHistory 棒棒!!
        • 通过URL变化来改变路由的,调用的是浏览器的History
        • 一般用于线上生产环境
      • createMemoryHistory
        • Memory history 并不会从地址栏中操作或读取,它能够帮助我们完成服务器端的渲染,或者用于测试以及其他渲染环境(比如React Native),和其他两种不一样的是,我们需要在内存中创建history对象来使用
        • createHashHistory & createBrowserHistory
  • webpack后段服务器

    • 在package.json中配置上 --history-api-fallback
     "start": "webpack-dev-server --progress --colors --content-base dist --history-api-fallback"
    
  • navigating 路由之间的切换

    • Link
    • browserHistory
    //handleSubmit通过form的onSubmit={this.handleSubmit}
    handleSubmit(e){
        e.preventDefault();//阻止form表单同步的提交;
        const username=e.target.elements[0].value;
        const repo=e.target.elements[1].value;
        const path=`/about/${username}/${repo}`;
        browserHistory.push(path);
    }
    
    • this.context.router
    //1:表单的 onSubmit提交后出发的handleSubmit事件;
    handleSubmit(e){
            e.preventDefault();//阻止form表单同步的提交;
            const username=e.target.elements[0].value;
            const repo=e.target.elements[1].value;
            const path=`/about/${username}/${repo}`;
            this.context.router.push(path)
        }
    
    //2:设置contextTypes;注意,这里不兼容react.PropTypes;必须下载prop-types插件;
    App.contextTypes={
         router:PropTypes.object
    };
    export default App;
    

Confirm Navigation

  • 路由跳转前确认,场景:询问是否保存数据,转场动画等;
    this.context.router.setRouteLeaveHook
//组件中
componentDidMount(){
    this.context.router.setRouteLeaveHook(this.props.route,this.leaveHook)
}
leaveHook(nextLocation){
    console.log(nextLocation)
    return 'you want leave?'
}
//contextTypes的设置
Contact.contextTypes={
    router:propTypes.object
};

你可能感兴趣的:(react基础知识快速学习)