真实DOM和虚拟DOM区别
react关于虚拟DOM和真实DOM
 虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React在用,无需真实DOM上那么多属性
 虚拟DOM最终一定会转为真实DOM放入页面
JSX
JSX: 全称JavsScript XML
 是react定义的一种类似于XML的JS扩展语法:JS + XML 本质是
 React.createElement(component, props, …children)方法的语法糖
jsx语法规则:
 1.创建虚拟DOM时,不要写引号;
 2.标签中要混入【js表达式】,要使用{}
 3.标签中样式的类名要用className来指定
 4.标签中的内联样式要用style={{color:‘white’}},属性名转为小驼峰
 5.VDOM每次创建只能有一个根标签
 6.标签必须闭合(单标签加 / 自闭合)
 7.关于标签首字母:
 1) 若首字母小写,那么React就会去寻找与之同名的<html标签>
 · 若找见,直接转为html同名元素
 · 若未找见,报错
 2) 若首字母大写,那么React就会去寻找与之同名的组件(component),
 · 若找到就使用
 · 若没有就会报错
 8.注释时先用{}包起来变成js表达式再注释
受控组件和非受控组件
非受控组件:表单中的数据,在需要的时候,“现用现取”
 (通过ref获得节点,进而访问到value值)
受控组件:表单中输入类的DOM,随着用户的输入,
 将值自动收集到State中,那么就称为受控组件
高阶函数和函数柯里化
高阶函数:如果一个函数符合下面2个规范中的任意一个,该函数即为高阶函数
 1.若A函数接收的参数是一个函数,那么A即为高阶函数
 2.若A函数调用的返回值依然是一个函数,那么A为高阶函数
 常见的高阶函数:
 Promise
 setTimeout
 arr.map()
 bind()
函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。
render(){
     return(
          <form onSubmit={this.handleLogin}>
            用户名:<input type="texnCht" onChange={this.saveFormData("username")} /><br/>
            密码:<input type="password" onChange={this.saveFormData("password")} /><br/>
            <button>登陆</button>
            </form>
      )
  }
saveFormData = (type) =>{
   return (event)=>{
        this.setState({[type]:event.target.value})
      }
}
 
不用高级函数和柯里化
render() {
     return (
         <form onSubmit={this.handleLogin}>
             用户名:<input type="texnCht" onChange={event => this.saveFormData(event, "username")} /><br />
             密码:<input type="password" onChange={event => this.saveFormData(event, "password")} /><br />
             <button>登陆</button>
         </form>
     )
 }
 saveFormData = (event, type) => {
     this.setState({ [type]: event.target.value })
 }
 
react生命周期
this.forceUpdate()(强制render())
 旧
 
 1.初始化阶段:由ReactDOM.render()触发 — 初次渲染
-  
constructor()
2. componentWillMount()
3. render()
4. componentDidMount() -  
更新阶段:由组件内部this.setState()或父组件重新render触发
- shouldComponentUpdate()
 - componentWillUpdate()
 - render()
 - componentDidUpdate()
 
 -  
卸载组件:由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()
 
 
父子组件执行顺序
 初始化阶段
 父-componentWillMount
 父-render
 子-componentWillMount
 子-render
 子-componentDidMount
 父-componentDidMount
 更新阶段
 父-componentWillReceiveProps
 父-shouldComponentUpdate
 父-componentWillUpdate
 父-render
 子-componentWillReceiveProps(// 第一次传的不算,第二次传的才会显示)
 子-shouldComponentUpdate
 子-componentWillUpdate
 子-render
 子-componentDidUpdate
 父-componentDidUpdate
 卸载组件
 父-componentWillUnmount
 子-componentWillUnmount
 新
 
 新的hook的区别:
 1. 取消了 componentWillMount
 componentWillReceiveProps
 componentWillUpdate
 2. 新增了 getDerivedFromProps(当组件中的state完全取决于外部传来的prop时,就要用该钩子)
 getSnapshotBeforeUpdate(访问更新前的 props 和 state等信息。需要与 componentDidUpdate() 方法一起使用,否则会出现错误)
diffing算法原理
经典面试题:
 1) react/vue中的key有什么作用?(key的内部原理是什么?)
 2) 为什么遍历列表时,key最好不要用index?
- 虚拟DOM中key的作用: 
  
-  
简单的说:key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用。
 -  
详细的说:当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟DOM】,
随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:a) 旧虚拟DOM中找到了与新虚拟DOM相同的key:
1.若虚拟DOM中的内容没变,直接使用之前的真实DOM
2.若虚拟DOM中的内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOMb) 旧虚拟DOM中未找到与新虚拟DOM相同的key
根据数据创建新的真实DOM,随后渲染到页面 
 -  
 
用index作为key可能会引发的问题:
-  
若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低 -  
如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题 -  
注意! 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,
仅用于渲染列表、用于简单的展示,使用index作为key是没有问题的。 
- 开发中如何选择key? 
  
- 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
 - 如果确定只是简单的展示数据,用index也是可以的。
 
 
跨域
-  
什么是跨域问题(跨域问题是浏览器对于ajax请求的一种安全限制)
(1) 同源策略
所处的位置和目标位置不同域(源)
http://localhost:3000/a
http://localhost:3000/b
https://localhost:3001/b
协议、主机名(域名)、端口号跨域问题仅当XMLHttpRequest(AJAX)请求时,会出现。
 
(2) 浏览器所特有的一个问题
 2. 如何解决
 (1)JSONP => 利用script标签没有跨域限制的漏洞(动态创建script标签,然后设置src属性就可解决跨域问题。需要服务的支持 只能发起GET请求)
 (2)CORS => 要想把所有跨域问题解决至少要配7个请求头
 (3)代理解决跨域
ref
1.祖父串形式的ref
render(){
   return(
        <div>
            <input type="text" ref="input1" />
            <button onClick={this.show}>点我提示左侧数据</button>
            <input type="text" ref="input2" onBlur={this.show2} placeholder="失去焦点提示数据"/>
        </div>
    )
}
show = ()=>{
    // const {refs:{input1:{value:a}}} = this 重命名
    const {input1} = this.refs
    alert(input1.value);
}
show2 = ()=>{
   const {input2} = this.refs
     alert(input2.value);
 }
 
2.回调形式的ref
render(){
    return(
        <div>
            <input type="text" ref={ c => this.input1 = c} />
            <button onClick={this.show}>点我提示左侧数据</button>
            <input type="text" ref={ c => this.input2 = c} onBlur={this.show2} placeholder="失去焦点提示数据"/>
        </div>
    )
}
show = ()=>{
    console.log(this);
    const {input1} = this
    alert(input1.value)
}
show2 = ()=>{
    const {input2} = this
    alert(input2.value)
}
 
3.createRef形式的ref
container = React.createRef()
container2 = React.createRef()
render(){
    return(
        <div>
            <input type="text" ref={this.container} />
            <button onClick={this.show}>点我提示左侧数据</button>
            <input type="text" ref={this.container2} onBlur={this.show2} placeholder="失去焦点提示数据"/>
        </div>
    )
}
show = ()=>{
    console.log(this.container); // {current: input}
    alert(this.container.current.value)
}
show2 = ()=>{
    alert(this.container2.current.value)
}
 
react函数入参经典写法
方式一
<input type="password" onChange={event => this.saveFormData(event, "password")} />
saveFormData = (event, type) => {
    this.setState({ [type]: event.target.value })
}
方式二
<input type="texnCht" onChange={this.saveFormData("username")} />
saveFormData = (type) =>{
   return (event)=>{
       this.setState({[type]:event.target.value})
     }
}
                















![[nesbot/carbon]轻松优雅的驾驭时间处理](https://img-blog.csdnimg.cn/img_convert/808a5b55bb0b163a0a5921f6f03e98e8.png)


