react.js

哈喽大家好,能和大家见面啦,我依旧是那个可爱的秃头小兄弟。
今天又周四了啊,划水人的一天,开心。
话不多说哈,直接搂代码

1.react 的特点

1.采用组件化模式。声明式编程,提高开发效率及组件复用率

2.在 React Native 中可以使用 React 语法进行移动端开发

3.使用虚拟 DOM+优秀的 Diffing 算法,尽量减少与真实 DOM 的交互

2.关于虚拟 DOM

1.本质上是 object 类型的对象(一般对象)

​ 2.虚拟 DOM 比较轻,真实 DOM 比较重,因为虚拟 DOM 是 React 内部在用,无需真实 DOM 上嫩么多的属性

3.虚拟 DOM 最终会被 React 转化为真实 DOM,呈现在页面上

// 1.创建虚拟dom
const VDOM = (
  <h1>
    <span>hello</span>
  </h1>
);
// 2.渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById("test"));

const demo = document.getElementById("demo");
console.log(typeof VDOM); //object
console.log(VDOM instanceof Object); //true

3.jsx 语法规则

jsx语法规则

1.定义虚拟DOM时,不能写引号

2.标签中混入js表达式,插值时要用{}

3.样式的类名不要用class,要用className

4.内联样式要用style={{key:value}},多单词要用小驼峰

5.只有一个根标签

6.标签必须闭合,单标签可使用自闭合

7.标签首字母

(1)若小写字母开头,则将改标签转为html中同名标签,若html中没对应标签,则标错

(2)若大写字母开头,react就去渲染对应的组件,若无定义,则报错

// 1.创建虚拟dom
const VDOM = (
  <div>
    <ul>
      <li className="sty">{dataObj.name}</li>
      <li style={{ color: "#fff", backgroundColor: "#666" }}>{dataObj.age}</li>
      <li>{dataObj.sex}</li>
      <li>{dataObj.msg.toLocaleLowerCase()}</li>
      <li>{dataObj.msg.toLocaleUpperCase()}</li>
      <li>{dataObj.msg.toLowerCase()}</li>
    </ul>
    <h2><input type="text" /></h2>
  </div>
);

4.语句与表达式的区别

一定要区分:js语句(代码)与js表达式

1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方

(1)a (2)a+b (3)demo(1) (4)arr.map (5)function test(){}

2.语句(代码)

下面这些都是语句(代码)流程语句,控制代码走向的

(1)if()

(2)for(){}

(3)switch(){case:xxx}

5.组件实例的三大特性

1.state

// 严重注意:状态必须通过setState进行更新,且更新是一种合并,不是替换

this.setState({ isHoet: !isHoet })

2.props

// props接收的数据是只读的,不能在内部修改数据

3.ref

//字符串ref
//1.给按钮命名
<input type="text" ref='inp2' onBlur={this.Blurs}/>
//2.使用refs获取到数据
 let { inp2 }=this.refs

 //回调函数ref
  <input type="text" ref={c => this.inp2 = c} onBlur={this.Blurs} />
 //回调函数接收的参数c/currentNode就是当前元素节点,this.inp2就是给类的实例对象加上一个inp2,获取到值
   let { inp1 } = this
 //获取到inp1的值

 //回调函数更新的时候会调用两次,先清空成null,再获取到节点。
 //class绑定函数的方式可以解决这个问题
 <input type="text" ref={this.saveInput} />
 saveInput = (c) => {
                console.log("@", c);
            }

createRef 的使用

//1.给class函数类的实例对象身上加一个myRef属性
myRef = React.createRef()
//2.在表单绑定
 <input type="text" ref={this.myRef2} onBlur={this.Blurs} />
//3.  获取到值
     Blurs = () => {
                alert(this.myRef2.current.value);
            }

// React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,缺点在于他是专用的,想要获取多个input值,需要再定义myRef2 = React.createRef()

6.事件处理

(1)通过onCxxx属性指定事件处理函数(注意大小写)

<input type="text" onBlur={this.Blurs} />

a.React使用的是自定义合成事件,而不是使用的原生DOM事件——为了更好的兼容性

b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了高效

(2)通过event.target得到发生事件的DOM元素对象——不要过度使用ref

Blurs = (event) => {

console.log(event.target.value);

}

7.高阶函数:函数的柯里化

高阶函数:如果一个函数符合以下2个规范中的任何一个,那该函数就是高阶函数

1.若A函数,接收的参数是一个函数,那么A函数就可以称为高阶函数

2.若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数

常见的高阶函数有:Promise setTimeout arr.mao()等等

函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式

// 正常写法
function sum(a, b, c) {
  return a + b + c;
}
let result = sum(1, 2, 3);
console.log(result);
// 函数柯里化
function msg(a) {
  return (b) => {
    return (c) => {
      return a + b + c;
    };
  };
}
let result2 = msg(1)(2)(3);
console.log(result2);

当事件需要传参数时,可使用高阶写法,处理函数中需要返回一个函数,也可以用回调函数的方式

//高阶函数
<input onChange={this.handleCheck(id)} />;
handleCheck = (id) => {
  return (event) => {};
};
//回调函数
<button onClick={() => this.handleDelete(id)}>删除</button>;
handleDelete = (id) => {};

8.生命周期

1. 组件从创建到死亡它会经历一些特定的阶段。

2. React 组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。

3. 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

生命周期回调函数=》生命周期钩子函数=》生命周期函数=》生命周期钩子

生命周期的三个阶段(旧)

// 卸载组件调用
ReactDOM.unmountComponentAtNode(document.getElementById("test"))

// 组件挂载完毕
componentDidMount() {}

// 组件将要销毁
componentWillUnmount() {}

 // 初始化渲染,状态更新之后
 render(){}

  /*1。初始化阶段: 由ReactDoM.render()触发--初次渲染
             1.constructor()
             2.componentWillMount()
             3.render()
             4.componentDidMount() =====> 常用
        般在这个例子中做一些初始化的事,例如: 开启定时器、发送网络请求、订阅消息
        2,更新阶段: 由组件内部this.setSate()或父组件render触发
             1.shouldComponentUpdate()
             2.componentWi1lUpdate()
             3.render() =====> 必须使用的一个
             4.componentDidupdate()
        3.卸载组件: 由ReactDoM.unmountComponentAtNode()触发
             1.componentwillUnmount() =====> 常川
        一般在这个钩子中做一些收尾的事,例如: 关闭定时器、取消订阅消息*/

生命周期的三个阶段(新)

 1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
1.constructor()
2.getDerivedStateFromProps
3.render()
4.componentDidMount() =====>
常用一般在这个例子中做一些初始化的事,例如: 开启定时器、发送网络请求、订阅消息
	2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.render()//必须使用的一个
4.getSnapshotBeforeUpdate
5.componentDidUpdate()
	3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1.componentwillUnmount() =====> 常川
一般在这个钩子中做一些收尾的事,例如: 关闭定时器、取消订阅消息

总结:新与旧的相比,即将要废弃三个钩子函数

componentWillMount()

componentWi1lUpdate()

componentWillReceiveProps

现在使用会出现警告,下一个大版本需要加上 UNSAFE\_前缀才能使用,以后可能会被彻底废弃,不建议使用。

同时提出俩个新的钩子

getDerivedStateFromProps

getSnapshotBeforeUpdata

9.key

总结:数据的更新就是使用diffing算法,通过对比key看看是不是同一个对象,
   如果是同一个,数据如果没改变直接复用之前的DOM,如果改变了就把新的虚拟DOM转化为真实DOM
   如果不是同一个,直接创建新的DOM
        使用index作为key值
        初始数据
         { id: 1, name: '小站', age: 18 },
         { id: 2, name: '小红', age: 19 },
         初始的虚拟dom
         <li key=0>1---小站--18}</li>
         <li key=1>1---小红--19}</li>

         更新后的数据
         { id: 3, name: '笑了', age: 20 }
         { id: 1, name: '小站', age: 18 },
         { id: 2, name: '小红', age: 19 },
        更新后的虚拟dom
         <li key=0>1---笑了--20}</li>
         <li key=1>1---小站--18}</li>
         <li key=2>1---小红--19}</li>
         使用id作为key值
        初始数据
         { id: 1, name: '小站', age: 18 },
         { id: 2, name: '小红', age: 19 },
         初始的虚拟dom
         <li key=1>1---小站--18}</li>
         <li key=2>1---小红--19}</li>

         更新后的数据
         { id: 3, name: '笑了', age: 20 }
         { id: 1, name: '小站', age: 18 },
         { id: 2, name: '小红', age: 19 },
        更新后的虚拟dom
         <li key=3>1---笑了--20}</li>
         <li key=1>1---小站--18}</li>
         <li key=2>1---小红--19}</li>
        


        1.react/vue中的key有什么作用(key的内部原理是什么)
        2.为什么遍历列表时,做好不要用index


        1.虚拟DOM中key的作用
          (1)简单的说:key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用
          (2)详细的说:当状态中的数据发生改变时,react会根据“新数据”生成“新的虚拟DOM”,
          随后React进行“新虚拟DOM”与“旧虚拟DOM”的diff比较,比较规则如下:

          a. 旧虚拟DOM中找到了与新虚拟DOM相同的key;
          (1)若虚拟DOM中内容没变,直接使用之前的真实DOM
          (2)若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

          b.旧虚拟DOM中未找到与新虚拟DOM相同的key
            根据数据创建新的真实DOM,随后渲染到页面

        2.用index作为key可能会引发的问题
          1.若对数据进行 逆向添加,逆向删除等破坏顺序操作
           会产生没有必须的真实DOM更新==》界面效果没问题,但效率低

          2.如果结构中还包含输入类的DOM
          会产生错误的DOM更新==》界面有问题

          3.注意!如果不存在对数据的逆序添加,逆序删除等破坏顺序的操作
          仅用于渲染列表用于展示,使index作为key是没有问题的

        3.开发中如何选择key
         1.最好使用每条数据的唯一标识作为key,比如id 手机号,身份证号,学号等唯一值
         2.如果确定只是简单展示数据,用index也可以
       

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值