不难懂--------react笔记

 
在jsx中不能使用class定义类名   由于class在js中是用来定义类的  定义类名的时候用className  
    label中的for必须写成htmlFor
 
 
    ReactDOM.render:    
        参数1:须要渲染的dom元素或者组件
        参数2:须要将渲染好的元素挂载在哪一个挂载点身上
        参数3:回调  成功的回调
 
   React中如何建立一个组件
        经过class类的方式来建立一个组件
 
        class 组件名称 extends React.Component
 
        注意:这个组件中必需要写一个render函数  函数中必须返回一个jsx语法
 
插槽做用:
插槽即:ReactDOM.createPortal(child, container) ,由ReactDom提供的接口。 能够实现将子节点渲染到父组件DOM层次结构以外的DOM节点。
第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 片断(fragment)。第二个参数(container)则是一个 DOM 元素。
应用场景:
对于 portal 的一个典型用例是当父组件有 overflow: hidden 或 z-index 样式,但你须要子组件可以在视觉上 “跳出(break out)” 其容器。例如,对话框、hovercards以及提示框。因此通常react组件里的模态框,就是这样实现的~
 
 
 
React.Component:
        是全部组件的父类。经过继承父类来建立组件。这个类中会包含不少方法(例如生命周期)
 
    render:
        是一个生命周期,用来渲染jsx语法
 
    constructor:   
        是一个生命周期函数,用来存放当前组件所须要的一些状态  状态存放在this.state中这个类中的this指向会指向当前这个组件
 
        注意:当书写了constructor后必需要写super不然this的指向会发生错误
 
     React中的事件绑定优化
        一、不须要传值的状况下去
            在constructor中定义函数  例如:this.handleClick = this.handleClick.bind(this)
            在render函数中使用定义好的函数 <button onClick={this.handleClick}>点击</button>
 
        二、须要传值的状况下
             <button onClick={this.handleClick.bind(this,须要传递的值)}>点击</button>
 
        三、不推荐使用
              <button onClick={()=>{
                    this.setState({
                        message:123
                    })
                }}>点击</button>
 
 
   setState:
        当须要修改this.state中的数据的时候咱们须要调用this.setState;
        this.setState这个方法是异步的
 
        书写方式2种
            一、
             this.setState({
                 key:val
             })
 
             二、this.setState((state)=>{
                    let str = (state.message + "").split("").reverse().join("")
                    return {
                        message:str
                    }
                })
 
 
        参数1:是一个对象 || 是一个函数  这个函数必须返回一个对象
 
        参数2:回调   做用:一、验证数据是否修改为功  二、获取数据更新后最新的DOM结构
 
     setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
 
    setState的“异步”并非说内部由异步代码实现,其实自己执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新以前,致使在合成事件和钩子函数中无法立马拿到更新后的值,形式了所谓的“异步”,固然能够经过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
 
    setState 的批量更新优化也是创建在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中若是对同一个值进行屡次 setState , setState 的批量更新策略会对其进行覆盖,取最后一次的执行,若是是同时 setState 多个不一样的值,在更新时会对其进行合并批量更新。
 
    forceUpdate
        这个方法用来作强制刷新
 
注意 :react  中一切皆为组件
 
react生命周期
 
constructor():(1次)     
                进行组件的初始化,且必需要写super函数,不然this指向会发生错误
                能够用this.state来定义当前组件所须要的一些状态
                当前生命周期特殊状况下接收不到props 的数据,若是想要接收到数据,须要在super和 constructor中传递props这个参数            
 
 
componentWillMount():(1次) 挂载前 (17.0版本废除了)
                当前生命周期能够接收到props传递过来的数据,能够将外部数据转化为内部数据
                注意尽可能不要使用this.state  由于当前生命周期执行完毕之后,下一个生命周期就是render函数  在当前生命周期中咱们能够对this.state中的数据作初始化的最后一次修改
 
 
render():(屡次) 渲染
                做用是将数据与虚拟DOM进行结合,进行数据渲染,而且在第一次执行完会将渲染结果在内存中保留一份
                第二次执行的时候会与内存中的虚拟DOM进行对比 这种方式叫作diff算法(新旧两个虚拟DOM的对比就是diff算法)
                key值的做用:
componentDidMount():挂载后(1次)
 
            当前生命周期能够获取到真实的DOM结构,通常状况下咱们能够在当前生命周期中进行Ajax的请求||进行方法的实例化
        如何获取到真实的dom结构
        一、this.refs  属性
        二、<元素  ref={(形参)=>this.属性 = 形参}></元素>
            这里面的形参表明的是当前的DOM元素   使用: this.属性
 
componentWillReceiveProps():(屡次) (废除)
        当props的数据发生改变的时候当前生命周期就会执行,当前是生命周期中有一个参数就是新的props
 
        在当前生命周期中能够用来检测外部数据的更新
 
shouldComponentUpdate()(屡次)
        一、当state||props中的数据发生改变的时候会执行当前生命周期,当前生命周期必需要返回一个布尔值, 当返回true的时候会执行
        下面的生命周期,若是返回false则下面的生命周期不会执行(render函数不会执行),
 
        二、当前生命周期中会有2(3)个参数 一个是新的props 一个是新的state。咱们能够经过新的props ||state 与 旧的props和state进行
        对比,来进行性能优化
 
        三、当前生命周期决定的是render函数是否渲染,而不是数据是否更新,哪怕返回值是false 数据其实也会进行更新的
 
        四、千万不要在这里面执行this.setState不然会形成死循环
 
componentWillUpdate:(屡次) (废除)
        当前生命周期能够用来作更新数据的最后一次修改
 
        当前生命周期中有2个参数一个是新的props 一个是新的state 咱们能够经过新的props || 新的state来作数据最后的一次更改
 
componentDidUpdate():(屡次)
        当前生命周期能够获取到数据更新后最新的DOM结构
 
        当前生命周期数据与模板已经进行相结合,生成最新的DOM结构了
 
        注意若是咱们在当前生命周期中作一些实例化的时候 必定要加判断
 
        当前生命周期也有2个参数 一个是旧的props 一个是旧的state
 
componentWillUnmont():卸载(一次)
        当前生命周期的做用来作事件的解绑 /  事件移除   等操做
 
 
 
面试题
 
面试题
一、组件加载的时候第一次执行的生命周期有哪些?
    constructor
    componentWillMount
    render
    componentDidMount
 
 
二、哪些生命周期会执行一次?
    constructor
    componentWillMount
    componentDidMount
    componentWillUnmount
 
 
三、哪些生命周期会执行屡次
    render
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    componentDidUpdate
 
四、当this.setState执行完毕之后会执行哪些生命周期
 
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate
 
五、当this.props发生改变的时候会执行哪些生命周期
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate
 
六、当组件的key值发生改变的时候会执行哪些生命周期
    componentWillUnmount
    constructor
    componentWillMount
    render
    componentDidMount
 
 
 
context  跨组件传值
 
一、经过react.createContext建立全局的GlobalContext来建立 一个 context
二、在根组件中经过GlobalContext.Provider建立一个全局的生产者
三、GlobalContext.provide中有一个属性value用来定义子组件所须要用到的状态值
四、在子组件中经过GlobalContext.Consumer来建立消费者。GlobalContext.Consumer内部必须经过一个函数来接收生产者的状态,且这个函数必须返回一个jsx语法。
 
 
路由
 
一、安装路由  cnpm install react-router-dom -S
 
二、引入react-router-dom  选择引入形式
   一、 HashRouter  : 路由的根组件  也是路由的一种形式 (hash路由)  带#号
            全部的路由的配置下项都必须在路由的根组件内部
    二、BrowerRouter  :  路由的根组件  也是路由的一种  (history路由)   不带#号
 
三、引入Router  Router 是路由渲染的方式
        经常使用的属性:
                path:路径
                component:须要渲染的组件  值是组件的名称
                render: 须要渲染的组件   值是组件
                exact:彻底匹配
 
四、路由跳转的方式   a标签   link   NavLink    编程式导航
 
        Link && NavLink区别?
        前者没有选中的标识 后者会有选中的标识
 
        场景:前者非TabBar 后者TabBar
 
    属性:
        activeClassName: 设置选中后的类名
        activeStyle:设置选中后的状态
    
五、Redirect:路由重定向
 
    属性:
        from:从哪里来
        to:到哪里去
        exact:彻底匹配
 
        最外层加上Switch
 
六、Switch
        Switch 是一个组件   做用是只匹配一个路由
 
七、路由的嵌套
 
        一、经过render的方式进行嵌套
 
        二、将嵌套的内容放到Switch的外面
 
八、路由的传参
 
    动态路由:(使用最多)
        一、在定义路由的时候/:属性的方式来定义传递的属性
        二、在路由跳转的时候传递须要传递的数据
        三、接收:this.props.match.params
 
    Query传值:
        一、在路由跳转的时候经过地址拼接的方式进行数据的传递(相似于get传值的方式)
        二、接收的时候经过this.props.loacltion.search 进行接收(注意须要url模块的解析)
        const url = require("url");
 
    对象传值:
        一、在路由跳转的时候经过对象的方式进行路由跳转
<li key={index}><Link to={{pathname:"/detail",query:{id:item.id,name:item.name}}}>{item.name}</Link></li>
        二、二、接收的时候经过this.props.location.query进行接收
        (注意:刷新浏览器的时候数据会丢失  慎用)
 
    
 
九、编程式导航:
    this.props.history.goBack()
    this.props.history.push()
    this.props.history.goForward()
    this.props.history.replace()
    例如:
        this.props.history.push({pathname:"/detail",query:{id:item.id,name:item.nam}})
 
render  与 component 的区别?
 
render:
    一、render能够渲染组件,以及标签
    二、render渲染方式能够进行组件传参
    三、render的渲染方式能够进行逻辑判断
    四、render的渲染方式能够进行路由嵌套
 
component:
    一、只能渲染组件,由于component的值是组件的名称,而不是组件标签
    二、component的值由于组建的名称不能传递,也不能作逻辑判断  以及路由嵌套
    三、只要经过component渲染的组件,身上会有三个属性 history  location match (优势)
 
 
函数组件与类组件的区别?
    函数组件:
        优势: 运行速度快  没有状态  也没有生命周期   只会有view层  相似于UI组件
 
    类组件:
        优势:能够存储组件所须要的状态  以及继承过来的一些生命周期的调用
 
Hooks:
    让函数组件拥有类组件的一些功能(存储状态  生命周期)
    useState : 函数   书写多个的
        存储当前组件所须要的一些状态
        参数:所须要的状态值
        返回值:数组
            一、当前状态的key值
            二、修改当前状态的函数
    hooks中的生命周期 : componentDidMount  componentDidUpdate  componentWillUnmount  (模拟出来的)
    useEffect:模拟类组件的一些生命周期
        参数1:函数
        参数2:依赖值
 
    若是第二个参数不写的状况下,参数1能够模拟 componentDidMount componentDidUpdate
 
    若是第二个参数书写的状况下,且第二个参数是一个不变值得状况下 第一个参数只能模拟 componentDidMount
 
    若是须要模拟componentWillUnmount 则只须要第一个参数中return 一个函数 在这个函数中作一些卸载组件的操做(事件的移除 解绑等)
        
 
flux: 公共状态管理
安装:cnpm install flux -S
    一、View
    
    二、Action
 
    三、Dispatcher
 
    四、Store
 
流程:
一、用户访问 View
二、View 发出用户的 Action
三、Dispatcher 收到 Action,要求 Store 进行相应的更新
四、Store 更新后,发出一个"change"事件
五、View 收到"change"事件后,更新页面
 
缺点:
    一、管理多个store
    二、频繁引入store
    三、UI组件  容器组件的拆分
    四、事件订阅每次都须要绑定
 
redux :公共状态管理
 
    安装 cnpm install redux -S
 
数据传递的流程:
    当组件须要修改数据的时候必须建立一个action,而后经过store.dispatch将action传递给store,store接收到action后将action传递给reducer,reducer接收到action后将action.type相比较,而后进行数据的修改,(要注意state只容许读不容许修改,深拷贝)数据修改完后返回一个新的state。最后经过store.subscribe通知全部组件数据更新。
 
深拷贝的问题:
     const newState = JSON.parse(JSON.stringify(state));
    会深度拷贝每个节点   这个过程是特别耗费性能的
 
持久化数据结构 immutable 一旦被建立就不会再被更改的数据
 
原理:结构共享
        特色:只要数据被修改就会返回一个新的immutable对象
 
 
fetch:
 
   fetch是 window下面的一个方法,脱离了XHR  是ES的规范  兼容性不太好   fetch基于promise的API
    
 
一、安装
    cnpm install whatwg-fetch -S
二、GET请求 默认就是get请求
 
fetch(url+?key=val,{
headers:请求头
method:请求的方式
})
 
三、post
fetch(url,{
headers:请求头
method:请求的方式
body:post传递参数的属性
})
 
 
特色:
无论post请求仍是get请求,当请求成功后第一个.then中是一个未处理的结果集
第二个.then中才是你想要的数据。fetch默认是不会携带cookie的,若是须要携带cookie则设置
credentials:"include"
 
 
 
fetch(url)
.then((res)=>{结果集的处理})
.then((data)=>{
console.log(data);
})
 
结果集的处理:你想要的数据格式是哪一种格式 text json blob formData
二、GET请求   默认即便get请求
 
    fetch(url+?key=val,{
        headers:请求头,
        method:请求方式
    })
 
三、POST请求
    fetch(url,{
        headers:请求头,
        method:请求方式
        body:post传递参数的属性
    })
 
特色:不管是post仍是get请求,当请求成功后的第一个.then中的是一个未处理的结果集
    第二个.then中才是你想要的数据。fetch默认不会携带cookie
 
 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它自己具备如下特征:
    从浏览器中建立 XMLHttpRequest
    从 node.js 发出 http 请求
    支持 Promise API
    拦截请求和响应
    转换请求和响应数据
    自动转换JSON数据
    客户端支持防止CSRF/XSRF
  fetch:
    符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
    更加底层,提供的API丰富(request, response)
    脱离了XHR,是ES规范里新的实现方式
    1)fetchtch只对网络请求报错,对400,500都当作成功的请求,须要封装去处理
    2)fetch默认不会带cookie,须要添加配置项
    3)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,形成了量的浪费
    4)fetch没有办法原生监测请求的进度,而XHR能够
 
purComponent:
一、 pureComponent表示一个纯组件,能够用来优化react程序。减小render函数渲染的次数。提升性能
  pureComponent进行的是浅比较,也就是说若是是引用数据类型的数据,只会比较不是同一个地址,而不会比较这个地址里面的数据是否一致
  浅比较会忽略属性和或状态突变状况,其实也就是数据引用指针没有变化,而数据发生改变的时候render是不会执行的。若是咱们须要从新渲染那么就须要从新开辟空间引用数据
  好处:
  当组件更新时,若是组件的props或者state都没有改变,render函数就不会触发。省去虚拟DOM的生成和对比过程,达到提高性能的目的。具体缘由是由于react自动帮咱们作了一层浅比较
 
二、使用场景
    一、PureComponent通常会用在一些纯展现组件上。切结props和state不能使用同一个引用
   二、在经过PureComponent进行组件的建立的时候不可以在写shouldComponentUpdate. 不然会引起警告
 
脚手架   cnpm install create-react-app -g
        create-react-app react-demo  后面是文件名
 
 
Immutable 
实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据建立新数据时,要保证旧数据同时可用且不变。同时为了不 deepCopy 把全部节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即若是对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。 Immutable 则提供了简洁高效的判断数据是否变化的方法,只需 === 和 is 比较就能知道是否须要执行 render(),而这个操做几乎 0 成本,因此能够极大提升性能。
 
1、immutable简介
    Immutable Data 就是一旦建立,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操做都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据建立新数据时,要保证旧数据同时可用且不变。同时为了不 deepCopy 把全部节点都复制一遍带来的性能损耗。
  
  在js中,引用类型的数据,优势在于频繁的操做数据都是在原对象的基础上修改,不会建立新对象,从而能够有效的利用内存,不会浪费内存,这种特性称为mutable(可变),但偏偏它的优势也是它的缺点,太过于灵活多变在复杂数据的场景下也形成了它的不可控性,假设一个对象在多处用到,在某一处不当心修改了数据,其余地方很难预见到数据是如何改变的,针对这种问题的解决方法,通常就像刚才的例子,会想复制一个新对象,再在新对象上作修改,这无疑会形成更多的性能问题以及内存浪费。
  为了解决这种问题,出现了immutable对象,每次修改immutable对象都会建立一个新的不可变对象,而老的对象不会改变
 
2、React中如何减小render函数渲染的次数
    在React中咱们知道当this.state 、this.props发生改变的时候render函数就会执行,但有些时候this.state、this.props没有发生改变的时候render函数也会执行(具体请自行了解相关案例,如需详解请留言)。那么咱们如何来减小render函数渲染的次数来提升React的性能优化?接下来咱们能够封装一个BaseComponent来减小React中render函数渲染的次数
    
i
注意:本文所进行优化的数据必须统一都是immutable数据,哪怕是this.props
 
 
00一、react中如何建立一个组件
方案一:ES6写法
    
class
组件名称
extends
Component
{ }
方案二:ES5写法
    
    
var App = React.createClass({})
 
00二、render函数何时会执行?
this.state 或者this.props发生改变的时候render函数就会执行
 
00三、react中如何对state中的数据进行修改?setState为何是一个异步的
修改数据经过this.setState(参数 1,参数2)this.setState是一个异步函数
参数1: 是须要修改的数据是一个对象,    
参数2: 是一个回调函数,能够用来验证数据是否修改为功,同时能够获取到数据更新后的DOM结构 等同于componentDidMount
this.setState中的第一个参数除了能够写成一个对象之外,还能够写成一个函数,函数中第一个值为prevState 第二个值为prePprops    
this.setState((prevState,prop)=>({}))
为何setState是一个异步的?当批量执行state的时候可让DOM渲染的更快,也就是说多个setstate在执行的过程当中还须要被合并
 
00四、react中如何定义自定义属性,以及限制外部数据的类型
一、自定义属性
    
组件名称.defaultProps={
        key:val
    }
 
二、限制外部数据的类型
    
    
a、引入propTypes第三方模块
    
b、类型限制
        
组件名称.propTypes={
            key:propTypes.类型
        }
 
00五、react路由经常使用的一些组件配置项有哪些?
BrowserRouter
HashRouter
       
withRouter
Route
Link
NavLink
Switch
Redirect
 
BrowserRouter 和 HashRouter是路由的根组件,跟组件下面只能有一个子元素
Route是路由路径所对应的组件
Link和 NavLink是进行路由的跳转。区别是当选中标签的时候NavLink会加上一个class
Swicth:被Switch包裹的Route渲染的时候只会渲染一个路径,建意:子页面不要放在Switch里面,主页面放在Switch里面
Redirect:设置路由的重定向
 
00六、reatc路由中Route渲染组件的方法有哪几种?区别是什么?
渲染方式有2种
    一、<Route path="/home"component={组件名称}></Route>
    经过component进行组件的渲染,这种方式的优势在于能够直接在组件的内部接受到history、location、match,缺点在于若是须要组件传参,或者渲染jsx语法的时候没法使用
    
    二、<Route path="/home" render={()=>{return<Home/>}}> </Route>
    经过render进行渲染组件,优势在于能够进行组件传参,还能够渲染非组件的标签,缺点在于若是须要使用 histroy  location   match的话须要在函数中传递过去
 
00七、如何控制路由的路径彻底匹配
给NavLink 或者 Route设置 exact属性
 
00八、react中路由传递参数的方法有哪些?
方案一:
     
//经过params进行传值
     <Router path="/one/:id"  render={(history)=>{
      return <One history={history}/>
      }}>
    
// html跳转:
    <NavLikn to={"/one/"+1}>one<NavLink>
    
// js跳转:
    
this.props.history.push('/one/'+'1')
 
    
// 接收值:
    在组件内部经过
constructor
参数进行接受
        
constructor({history,location,match}){
         super();
            /进行接受
            console.log( match.params)}
 
// 方案二:
    // 经过query
        <Router path="/one" render={(history)=>{
           return <One history={history}/>
        }}>
    
// html跳转:
        <NavLikn to={{ pathname:"/one", query:{data:1}}}>one<NavLink>
    
// js跳转:
    
this.props.history.push({ pathname : '/one',query : { data:1} })
    
// 获取值
    
this.props.location.query.data
注意:若是经过render进行渲染的时候须要在回调中将history的值传递过去.若是是component进行渲染的话,咱们只须要经过
this.props进行接受便可。
 
00九、react中的编程式导航方法有哪些?
this.props.history.push("须要跳转的路径");跳转路径
this.props.history.back();返回
this.props.history.forward():前进
this.props.history.replace():替换
 
0十、react中的生命周期有哪些?
(1)、组件建立的过程
    constructor
    componentWillMount
    render
    componentDidMount
(2)当props中的数据发生改变后会执行哪些生命周期函数
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate
(3)组件销毁的时候
    componentWillUnmount
 
0十一、reatc中如何强制更新DOM
this.foreUpdate()
 
0十二、谈谈你对react生命周期中shouldComponentUpdate的理解
shouldComponentUpdate是react性能优化很是重要的一环。
组件接受新的
state或者props时调用,咱们能够设置在此对比先后两个props和state是否相同,若是相同则返回false阻止更新,由于相同的属性状态必定会生成相同的dom树,这样就不须要创造新的dom树和旧dom树进行diff算法对比,节省大量性能,尤为是在dom结构复杂的时候
 
01三、谈谈你对虚拟DOM的理解,以及好处?
虚拟DOM:虚拟DOM其实就是真实的js对象虚拟DOM提升了react的性能,每次数据更新后都会从新计算上虚拟DOM,并和上一次的虚拟DOM进行对比,对方法变化的部分进行批量更新。react中也提供了
shouldComponentUpdate生命周期的回调,来减小数据变化后没必要要的虚拟DOM对比过程。保证性能
 
01四、谈谈你对flux的理解
利用单项数据流的方式来组合react的视图组件,它是一种模式,而不是一种框架
简单来讲flux能够帮咱们解决非父子组件之间传值
flux数据传递流程
   
https://www.cnblogs.com/nanianqiming/p/9870194.html
 
01五、react17废除的生命周期函数,与新增的生命周期函数
因为将来采用异步渲染机制,因此即将在 17版本中去掉的生命周期钩子函数
  componentWillMount
  componentWillRecieveProps
  componentWIllUpdate
  
新增的生命周期
staticgetDerivedStateFromProps(nextProps, prevState){}用于替换componentWillReceiveProps,能够用来控制 props 更新 state的过程;它返回一个对象表示新的 state;若是不须要更新,返回null便可在每次渲染以前都会调用,无论初始挂载仍是后面的更新都会调用,这一点 和componentWillReceiveProps不一样(只有当父组件形成从新渲染时才调用) 每次都应该返回一个对象做为
   
   
  getSnapshotBeforeUpdate() {}
  
  用于替换 componentWillUpdate,该函数会在update后 DOM 更新前被调用,
  用于读取最新的 DOM 数据,返回值将做为 componentDidUpdate 的第三个参
  数,在最新的渲染数据提交给DOM前会当即调用,它让你在组件的数据可能要改
  变以前获取他们    
    
   componendDidCatch(error, info){}
   
   若是一个组件定义了componentDidCatch生命周期,则他将成为一个错误边
   界(错误边界会捕捉渲染期间、在生命周期方法中和在它们之下整棵树的构造
   函数中的错误,就像使用了trycatch,不会将错误直接抛出了,保证应用的
   可用性)
   
 
01六、this.setState以后react作了哪些操做
  一、shouldComponentUpdate
  二、componentWillUpdate
  三、render
  四、componentDidUpdate
 
01七、当组件的key值发生改变后会执行哪些生命周期函数?
1、componentWillUnmount
2、constructor
三、componentWillMount
四、render
5、componentDidMount
 
01八、在react中是否封装过组件?封装组件须要注意的地方?
经常使用封装组件用到的东西
一、propTypes  限制外部数据的类型
二、defaultProps  设置默认的外部数据
三、父传子  子传父  context  等传值方式
四、高阶组件
封装组件的时候必定要注意组件的复用性,灵活性
 
01九、如何接收组件内部的标签/内容
经过 this.props.children
 
020、请说下你对redux的理解,以及使用的方式
其实redux就是Flux的一种进阶实现。它是一个应用数据流框架,
主要做用应用状态的管理
redux的三大原则
    
1、单一的数据源
    
2、state是只读的
    
3、使用纯函数来进行修改redux中有
3个经常使用的方法  
    
1、createStore()       建立store
    
2、combineReducers()   合并多个reducer
    
3、applyMiddleware()   使用中间件,处理异步的action
 
redux数据传递的流程
    当组件须要改变Store数据的时候。须要建立一个Action,而后经过dispatch(action) 传递给Store,而后Store把Action转发给Reducers.Reducers会拿到previousState(之前的state
数据) 和action。而后将previousState和action进行结合作新的数据(store)修改。而后生成一个新的数据传递给Store 。Store经过触发subscribe()这个方法来调用函数执行setState使得view的视图发生改变
 
00一、请说下在react中如何处理异步的action
经过applyMiddleware来使用中间件来处理action
经常使用的中间件
    redux-promise-middleware
    redux-thunk
    redux-saga
 
00二、请说下redux中中间件的理解
中间件:请求和回复之间的一个应用。
在redux中中间件是dispatch与reducer之间的一个应用
 
00三、请说下redux中你对reducers的理解,以及如何合并多个reducers
在redux中reducer是一个纯函数,其中这个纯函数会接收
2个参数一个是state一个是action。state用来保存公共的状态,state有一个特色就是只容许读不容许进行修改 。在实际开发中由于会涉及到多人协做开发因此每一个模块都会有一个reducer。
咱们能够经过combineReducers来合并多个reducers
 
00四、请说下你对高阶组件的理解,以及做用高阶组件就是接受一个组件做为参数,返回一个相对加强性的组件的函数高阶组件是一个函数 并非组件
做用:
    一、属性代理
---主要进行组件的复用
    二、反向集成
---主要进行渲染的劫持
 
00五、在react中如何解决单页面开发首次加载白屏现象
一、经过路由懒加载的方式  react-loadable
二、首屏服务端渲染
 
00六、请说下react中key值的理解
react利用key来识别组件,它是一种身份标识标识,相同的key react认为是同
一个组件,这样后续相同的key对应组件都不会被建立
有了key属性后,就能够与组件创建了一种对应关系,react根据key来决定是销毁
从新建立组件仍是更新组件。
key相同,若组件属性有所变化,则react只更新组件对应的属性;没有变化则不
更新。
key值不一样,则react先销毁该组件(有状态组件的componentWillUnmount会执行)
,而后从新建立该组件(有状态组件的constructor和componentWillUnmount都会执行)
 
00七、组件第一次执行的时候会执行哪些生命周期函数
constructor
componentWillMount
render
componentDidMount
 
00八、哪些生命周期会执行屡次
render
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
 
00九、当this.state 或者this.props发生改变的时候会执行哪些生命周期函数
this.state
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate
this.props
    componentWillReceiveProps
    shouldComponentUpdate
    componentWillUpdate
    render
    componentDidUpdate
 
0十、谈谈你对context的理解
当你不想在组件树中经过逐层传递props或者state的方式来传递数据时,可使用
Context来实现跨层级的组件数据传递,使用context能够实现跨组件传递
旧版context的基本使用
  一、getChildContext根组件中声明,一个函数,返回一个对象,  就是context
  二、childContextTypes根组件中声明,指定context的结构类型, 如不指定,会产生错误
  三、contextTypes子孙组件中声明,指定要接收的context的结构类型, 能够只是context的一部分结构。contextTypes没有定义,context将是 一个空对象。
  四、this.context在子孙组件中经过此来获取上下文
 
新版
context的基本使用
    一、根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)
    二、组件引入GlobalContext并调用context,使用GlobalContext.Consumer
 
0十一、谈谈你对react中withRouter的理解默认状况下必须是通过路由匹配渲染的组件在
this.props上拥有路由参数,才能使用编程式导航的写法,withRouter是把不是经过路由切换过来的组件,将react-router 的 history、location、match 三个对象传入props对象上
 
简单的来讲就是否是路由包裹的组件也可使用路由的一些方法
 
0十二、说如下你对puerComoponent的理解pureComponent表示一个纯组件,能够用来优化react程序。减小render函数渲染的次数。提升性能
pureComponent进行的是浅比较,也就是说若是是引用数据类型的数据,只会比较不是同一个地址,而不会比较这个地址里面的数据是否一致
好处:当组件更新时,若是组件的props或者
state都没有改变,render函数就不 会触发。省去虚拟DOM的生成和对比过程,达到提高性能的目的。具体缘由是由于react自动帮咱们作了一层浅比较
 
01三、react请求接口数据是在componentDidMount 仍是componentWillMount周期好
若是你要获取外部数据并加载到组件上,只能在组件"已经"挂载到真实的网页上才能做这事情,其它状况你是加载不到组件的。componentDidMount方法中的代码,是在组件已经彻底挂载到网页上才会调用被执行,因此能够保证数据的加载React异步渲染开启的时候,componentWillMount 就可能被中途打断,中断以后渲染又要重作一遍,若是在componentWillMount 中作 AJAX 调用,代码里看到只有调用一次,可是实际上可能调用 N 屡次,这明显不合适。相反,若把 AJAX 放在componentDidMount,由于 componentDidMount 在第二阶段,因此绝对不会屡次重复调用,这才是 AJAX 合适的位置
 
1、React中key值得做用
react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的,而是给React本身使用,有了key属性后,就能够与组件创建了一种对应关系,简单说,react利用key来识别组件,他是一种身份标识,就像每一个人有一个身份证来作辨识同样。每一个key 对应一个组件,相同的key react认为是同一个组件,这样后续相同的key对应组件都不会被建立
 
key值相同
若是两个元素是相同的key,且知足第一点元素类型相同, 若元素属性有所变化,则React只更新组件对应的属性,这种状况下,性能开销会相对较小
 
key值不一样
在render函数执行的时候,新旧两个虚拟DOM会进行对比,若是两个元素有不一样的key,那么在先后两次渲染中就会被认为是不一样的元素,这时候旧的那个元素会被unmount,新的元素会被mount
//更新前
render(){
return ( <List key = '1'/>);
}
//更新后
render(){
return (
     <List key = '2'/>
  );
}
 
2、例子
//tree1
<ul>
<li key='1'>1</li>
<li key='2'>2</li>
</ul>
//tree 2
<ul>
<li key='1'>1</li>
<li key='3'>3</li>
<li key='2'>2</li>
</ul>
若是没有key值得状况下,react并不会执行插入操做,他直接会移除原先的第二个子元素,而后再append进去剩下的子元素,而其实咱们这个操做只只须要一个insert操做就能完成。为了解决这种问题,react须要咱们提供给一个key来帮助更新,减小性能开销
 
若是有key值得状况下,react就会经过key来发现tree2的第二个元素不是原先tree1的第二个元素,原先的第二个元素被挪到下面去了,所以在操做的时候就会直接指向insert操做,来减小dom操做的性能开销
 
3、不推荐用属性中的index来作key值
大部分状况下咱们要在执行数组遍历的时候会用index来表示元素的key。这样作其实并非很合理。咱们用key的真实目的是为了标识在先后两次渲染中元素的对应关系,防止发生没必要要的更新操做。那么若是咱们用index来标识key,数组在执行插入、排序等操做以后,原先的index并再也不对应到原先的值,那么这个key就失去了自己的意义,而且会带来其余问题
 
4、注意事项
React中的key 值必须保证其惟一和稳定性
下面案例中key的值以Math.random() 随机生成而定,这使得数组元素中的每项都从新销毁而后从新建立,有必定的性能开销
{
  dataList.map((item,index)=>{
      return <div style={mystyle} key={Math.random()}>{item.name}</div>
      })
}
 
 
1、react-hooks概念
 
 
  React中一切皆为组件,React中组件分为类组件和函数组件,在React中若是须要记录一个组件的状态的时候,那么这个组件必须是类组件。那么可否让函数组件拥有类组件的功能?这个时候咱们就须要使用hooks。
 
  Hooks让咱们的函数组件拥有了相似类组件的特性,Hook是React16.8中新增的功能,它们容许您在不编写类的状况下使用状态和其余React功能
 
 
2、为何React中须要类组件
 
  一、须要记录当前组件的状态
  二、须要使用组件的一些生命周期函数
 
两者对比以后是否是感受Hooks简单好多了?那么接下来咱们来学习Hooks
 
 
4、Hooks基本使用
 
  一、Hooks经常使用的方法
    useState 、useEffect 、useContext以上三个是hooks常常会用到的一些方法
 
 
  二、useState
    useState是react自带的一个hook函数,它的做用就是用来声明状态变量.useState这个函数接收的参数是咱们的状态初始值,它返回了一个数组,这个数组的第 [0]项是当前的状态值,第 [1]项是能够改变状态值的方法函数。
 
 
      useState : 建立一个状态,这个状态为0
  count : 表明当前状态值也就是0
  setCount : 更新状态的函数
  addCount = ()=>setCount(count+1);调用setCount就能够用来修改状态
 
 
 
    2-一、useState返回的是什么?
        const[count,setCount] = useState(0);
        const state = useState(0);
        const count = state[0];
        const setCount  = state[1]
 
    注意:
    一、useState必定要写在函数初始的位置不能在循环或判断语句等里面调用,这样是为了让咱们的 Hooks 在每次渲染的时候都会按照 相同的顺序 调用,由于这里有一个关键的问题,那就是 useState 须要依赖参照第一次渲染的调用顺序来匹配对于的state,不然 useState 会没法正确返回它对于的state
    二、咱们能够在一个函数组件中使用多个
export default()=>{
    let[count,setCount] = useState(0);
      let[count,setCount] = useState(0);
      let[count,setCount] = useState(0);
    }
 
 
5、useEffect基本使用
  咱们写的有状态组件,一般会产生不少的反作用(side effect),好比发起ajax请求获取数据,添加一些监听的注册和取消注册,手动修改dom等等。咱们以前都把这些反作用的函数写在生命周期函数钩子里,好比componentDidMount,componentDidUpdate和componentWillUnmount。而如今的useEffect就至关与这些声明周期函数钩子的集合体。它以一抵三。
 
 
(useEffect = componentDidMount+componentDidUpdate+componentWillUnmount)
 
  5-一、useEffect
    useEffect中有两个参数,第一个参数是一个函数,第二个参数是一个依赖的数据。第二个参数用来决定是否执行里面的操做,能够避免一些没必要要的性能损失,只要第二个参数中的成员的值没有改变,就会跳过这次执行。若是传入一个空数组 [ ],那么该effect 只会在组件 mount 和 unmount 时期执行。
 
 
  5-二、useEffect模拟componentDidMount && componentDidUpdate
importReact,{useState,useEffect}from"react"
export default()=>{
    let[title,setTitle] = useState(0);
    letupdateTitle =()=>setTitle(title+1);
    return(
        <div>
            <h2>{title}</h2>
            <button onClick={updateTitle}>点击</button>
        </div> )
    
    
//参数是一个函数  每次mount 或者 update都会调用当前函数
    useEffect(()=>{
        document.title =`页面为${count}`;
    })
    }
 
5-三、如何只在componentDidMount中执行
import React,{useState,useEffect} from"react" export default()=>{
    let[title,setTitle] = useState(0);
    let updateTitle =()=>setTitle(title+1);
    return(
        <div>
            <h2>{title}</h2>
            <buttononClick={updateTitle}>点击</button>
        </div>
    )
    
    
//将第二个参数设置为一个空数组则只会在componentDidMount中执行
    useEffect(
()=>{document.title =`页面为${count}`;    },[])}
 
 
5-二、useEffect模拟componentWillUnMount
  useEffect 中还能够经过让函数返回一个函数来进行一些清理操做,好比取消订阅等
 
useEffect =(()=>{
    return()=>{
        //unmount时调用这里
        document.removeEventListener();
    }
},[])
 
4、useEffect 何时执行?
  它会在组件 mount 和 unmount 以及每次从新渲染的时候都会执行,也就是会在 componentDidMount、componentDidUpdate、componentWillUnmount 这三个时期执行
 
5、hooks的好处
  面向生命周期编程变成了面向业务逻辑编程
 
 
6、fetch与axios的区别
axios("http://xxx/xxx.json?a=123'").then((res)=>{
     consol.log(res)//这里的r是响应结果})
fetch("http://www.baidu.com").then( (res)=>{
        console.log(res);//是一个综合各类方法的对象,并非请求的数据
})
fetch返回的是一个未处理的方法集合,咱们能够经过这些方法获得咱们想要的数据类型。若是咱们想要json格式,就执行response.json(),若是咱们想要字符串就response.text()
 
axios
        一、从浏览器中建立 XMLHttpRequest
        二、从 node.js 发出 http 请求
        三、支持 Promise API
        四、拦截请求和响应
        五、转换请求和响应数据
        六、自动转换JSON数据
        七、客户端支持防止CSRF/XSRF
fetch:
    符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
    更加底层,提供的API丰富(request, response)
    脱离了XHR,是ES规范里新的实现方式
 
一、fetchtch只对网络请求报错,对400,500都当作成功的请求,须要封装去处理
 
二、fetch默认不会带cookie,须要添加配置项
 
三、fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实
现的超时控制并不能阻止请求过程继续在后台运行,形成了量的浪费
 
四、fetch没有办法原生监测请求的进度,而XHR能够
相关文章
相关标签/搜索