react 基础

jsx 基础知识介绍

我们可以直接引⼊ react.js 和 react-dom.js 两个库,使⽤
react 时,我们可以使⽤ jsx 语法来书写我们的模版

<div className="foo">bar</div>

这是⼀种⾮常类似 DOM 的 xml 结构的语法,唯⼀有区别
的是,我们可以在 jsx 中使⽤ {} 来使⽤ js 表达式

<div className="foo">{something ? "something is
true" : "something is false"}</div>

这⾥的表达式当然也可以执⾏函数,数组 map 等等形
式,只需要这个式⼦是⼀个表达式即可,但这⾥要注意
千万不能直接在 jsx 中写执⾏诸如 if else 的形式,可以把
它改造成⼀个三⽬运算符

<div className="foo">{if(xx) {xx} else {xx}}
</div> // 错误

在 jsx 中我们需要保证渲染的内容必须是合法的 jsx 元
素,合法的 jsx 元素有:

  • 普通的 DOM 标签,如 div/p/span 等等
  • 声明的 react 组件,例如通过 class 或函数创建的 jsx 组件
  • null(最终会渲染⼀个空元素)
  • 字符串(最终会渲染⼀个 text 节点)
  • 对于数字类型,最终就会渲染出来,所以有的时候通过布尔表达式判断的时候就会有问题
{false && (<p>this is false</p>)} // 不会渲染内容
{0 && (<p>this is false</p>)} // 会渲染 0

我们可以通过 React.isValidElement 来判断⼀个内容元素是不是⼀个合法的 react element。
同时需要注意的是,因为 class / for 这类的 html 属性是关键字,所以在 jsx 中我们想要使⽤,就必须使⽤className/htmlFor 的形式来定义

<label className="foo"
htmlFor="name">label</label>

事实上我们并不能直接在浏览器中使⽤ jsx 内容,我们需要搭配⼀些编译库将 jsx 语法进⾏编译。⽐较知名的就是 babel,搭配 babel-plugin-transform-react-jsx 插件,可以将 jsx 编译为 react 的内部⽅法。

例如这个例⼦,经过 babel 和配套插件就可以将这种形式进⾏编译:

<div>
 <h3 className="h3">{something ? "something is true" : "something is false"}</h3>
</div>

最终结果即为:

React.createElement(
 "div",
 null,
 React.createElement(
 "h3",
 {className: 'h3'},
 something ? "something is true" :
"something is false"
 )
);

React.createElement 主要分为三类参数,第⼀个是组件的名字,第⼆个参数是当前组件接受的属性,第三个之后的参数都是当前组件嵌套的⼦组件。

jsx 总结

  • jsx 是⼀种语法糖,我们需要将他们编译为React.createElement的形式
  • 写 jsx 需要注意类型必须合法,尤其是写布尔表达式的时候需要额外注意,尽量使⽤三⽬运算符来书写 jsx
  • 需要注意 class 和 for 标签在书写时需要改为classNamehtmlFor

create-react-app cli 的使⽤

create-react-app 是 react 官⽅维护的⼀个 cli ⼯具,⾥⾯封装了 webpack babel 等基本的⼯程化⼯具,让我们能快速上⼿和使⽤。当然,我们也可以⾃⼰封装 webpack 配置来进⾏使⽤,封装⼀个可以编译 react 应⽤的脚⼿架⾮常简单,只需要配置所有 react ⽂件使⽤ babel + babel 转译 jsx 插件即
可,最终编译的 js 内容即可直接应⽤于⻚⾯中。
有时候我们可以⾃⼰封装⼀些符合公司内部前端架构的cli 应⽤。例如我们可以封装⼀个使⽤ ts 书写 react 应⽤的脚⼿架来为我们⾃⼰所⽤。

react中函数组件和 class 组件/受控组件和⾮受控组件

function Foo(props) { return (<div>{props.text
|| 'Foo'}</div>); }
 
class Bar extends React.Component {
 render() {
 return (
 <div>{this.props.text || 'Bar'}</div>
 );
 } 
}

这两种形式有何区别呢?我们简单对⽐⼀下:

  • 加载的 props ⽅式不同,函数式定义组件从组件函数 的参数加载。class 形式的组件通过 this.props 获取传 ⼊的参数
  • 函数式组件⽐较简单,内部⽆法维护状态。class 形式 内部可以通过 this.state 和 this.setState ⽅法更新内部state 和更新内部 state,同时更新 render ⾥⾯的函数 渲染的结果。
  • class 组件内部可以定义更多的⽅法在实例上,但是函 数式组件⽆法定义。

事实上,函数式组件和 class 组件之间的区别也仅停留在部分组件确实不需要维护内部状态。class 组件定义稍微复杂⼀些,但是内部可以维护更多的⽅法和状态。

react组件⽣命周期

生命周期流程图 (引用自linjinhe 的博客)

  1. 加载阶段(Mounting):在组件初始化时执行,有一个显著的特点:创建阶段生命周期函数在组件的一辈子中只执行一次;

constructor()
加载的时候调用一次,可以初始化state static getDerivedStateFromProps(props, state)组件每次被Rerender的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新props/state之后;每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state

render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

componentDidMount()
组件渲染之后调用,只调用一次

  1. 更新阶段(Updating):属性和状态改变时执行,根据组件的state和props的改变,有选择性的触发0次或多次;

render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

getSnapshotBeforeUpdate(prevProps, prevState)
触发时间: update发生的时候,在render之后,在组件dom渲染之前;返回一个值,作为componentDidUpdate的第三个参数;配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法

componentDidUpdate()
组件加载时不调用,组件更新完成后调用

  1. 卸载阶段(Unmounting):在组件对象销毁时执行,一辈子只执行一次;

componentWillUnmount()
组件渲染之后调用,只调用一次

react常⻅错误和性能问题

1. 异步过程使⽤单例的 event 对象
全局单例的 event 对象,所以在异步对象中使⽤ react 事件时需要额外注意。异步操作最好将对象内部需要的值先进⾏拷⻉赋值。

 handleClick(e) {
 	setTimeout(function() {
 		console.log('button1 click',
		e.currentTarget.innerText); // 错误
	 }, 1000);
	console.log('button1 click',
	e.currentTarget.innerText);
 }

组件⽣命周期,它描述了整个组件在创建、实例化、销毁过程中不同过程中执⾏的⽅法。我们需要特别注意,不要在 render 中定义单独引⽤的内容。也就是不要在render 中使⽤箭头函数,否则很容易运⾏时造成⼦组件的重新渲染。
为了保证这种引⽤的相等,我们都会使⽤ immutable 的不可变数据,来保证组件间传递的数据引⽤相等。

2.性能优化⽅式

  • 使⽤ react dev tools ,检测组件是否出现不必要的重新渲染。
  • why-did-you-render
    why did you render 是⼀个能检测你的⻚⾯中的元素是否出现了不必要的重渲染。我们可以将它应⽤于我们的项⽬中,来检测是否有⽆
    意义的渲染的情况。
  • class 中提前声明箭头函数,保证 render 执⾏过程中 的函数不会因为引⽤问题导致重新渲染。

3.介绍 immutable 库 immutable-js 和 immer
为了配合 shouldComponentUpdate 来进⾏性能优化,⼤部分时候我们需要复杂的层级判断,这⾥我们介绍两个配合 react 最⼩更新的 immutable 库 immutable-js 和immer。
immutable-js 是 facebook 的⼯程师在 2014 年推出的,immer 则是 mobx 作者 2018 年推出的。他们的推出其实是为了实现不可变数据,但实际上这种做法更多的是为了优化我们的 react 应⽤⽽做的。
我们可以简单看⼀下 immutable-js 的⽤法,着重讲⼀下immer 的原理,便于⼤家更好的理解数据传递过程中的不可变性。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React基础面试题通常包括以下几个方面: 1. React中函数组件和类组件的区别是什么? 函数组件是一个简单的JavaScript函数,接受props作为参数并返回一个React元素。它通常用于展示静态内容或处理简单的交互逻辑。类组件是通过ES6的class语法创建的,继承自React.Component,可以使用state来管理内部状态以及使用生命周期方法,适用于复杂的逻辑和状态管理。 2. 在React中,keys的作用是什么? 键(keys)是React中用于识别和跟踪组件列表中每个元素的特殊属性。它们帮助React准确地更新和重排组件,提高性能。在遍历生成列表的时候,为每个元素添加唯一的键,可以帮助React更好地识别元素的变化,避免不必要的重新渲染。 以上回答参考了引用和引用中的内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [2022必备react面试题 附答案](https://blog.csdn.net/It_kc/article/details/121773566)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【前端面试题】—30道常见React基础面试题(附答案)](https://blog.csdn.net/snsHL9db69ccu1aIKl9r/article/details/115339484)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [面试题-基础.doc](https://download.csdn.net/download/Sheng_zhenzhen/12576734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值