React 使用中值得优化的 7 个点,前端400道面试题通关宝典助你进大厂

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

通过该组件的 props ,我们可看到它们都与组件提供的功能密切相关。

该组件看起来并无大碍,但如果将其中的一些 props 分担到子组件,那么数据流就会更清晰。

现在,我们已经看到该表单组件只处理提交和取消动作,其他范围内的事情,都交给了对应的子组件。

是否传递了很多有关配置的 props

在某些情况下,将多个有关配置的 props 组合成一个 options 是个不错的实践。

假设我们有一个可显示某种表格的组件:

<Grid

data={gridData}

pagination={false}

autoSize={true}

enableSort={true}

sortOrder=“desc”

disableSelection={true}

infiniteScroll={true}

/>

我们可以很清楚地看出,该组件除了 data 外其余的 props 都是与配置有关的。

如果将多个配置 props 合成为一个 options ,就可更好地控制组件的选项,规范性也得到提升。

const options = {

pagination: false,

autoSize: true,

enableSort: true,

sortOrder: ‘desc’,

disableSelection: true,

infiniteScroll: true,

}

<Grid

data={gridData}

options={options}

/>

props 的不兼容性

避免组件之间传递不兼容的 props

假设你的组件库中有一个 <Input /> 组件,而该组件开始时仅用于处理文本,但过了一段时间后,你将它用于电话号码处理。

你的实现可能如下:

function Input({ value, isPhoneNumberInput, autoCapitalize }) {

if (autoCapitalize) capitalize(value)

return <input value={value} type={isPhoneNumberInput ? ‘tel’ : ‘text’} />

}

问题在于,isPhoneNumberInput 与 autoCapitalize 之间并不存在关联,将一个手机号首字母大写是没有任何意义的。

在这种情况下,我们可以将其分割成多个小组件,来明确具体的职责,如果有共享逻辑,可以将其放到 hooks 中。

function TextInput({ value, autoCapitalize }) {

if (autoCapitalize) capitalize(value)

useSharedInputLogic()

return 

}

function PhoneNumberInput({ value }) {

useSharedInputLogic()

return 

}

虽然上面例子有点勉强,可当发现组件的props存在不兼容性时,是时候考虑拆分组件了。

props 复制为 state

如何更好地将 props 作为 state 的初始值。

有如下组件:

function Button({ text }) {

const [buttonText] = useState(text)

return {buttonText}

}

该组件将 text 作为 useState 的初始值,可能会导致意想不到的行为。

实际上该组件已经关掉了 props 的更新通知,如果 text 在上层被更新,它将仍呈现 接受到 text 的第一次值,这更容易使组件出错。

一个更实际场景是,我们想基于 props 通过大量计算来得到新的 state

在下面的例子中,slowlyFormatText 函数用于格式化 text,注意 需要很长时间才能完成。

function Button({ text }) {

const [formattedText] = useState(() => slowlyFormatText(text))

return {formattedText}

}

解决此问题 最好的方案是 使用 useMemo 代替 useState

function Button({ text }) {

const formattedText = useMemo(() => slowlyFormatText(text), [text])

return {formattedText}

}

现在 slowFormatFormat 仅在 text 更改时运行,并且没有阻断 上层组件更新。

进一步阅读:Writing resilient components by Dan Abramov。

返回 JSX 的函数

不要从组件内部的函数中返回 JSX

这种模式虽然很少出现,但我还是时不时碰到。

仅举一个例子来说明:

function Component() {

const topSection = () => {

return (

Component header

)

}

const middleSection = () => {

return (

Some text

)

}

const bottomSection = () => {

return (

Some footer text

)

}

return (

{topSection()}

{middleSection()}

{bottomSection()}

)

}

该例子虽然看起来没什么问题,但其实这会破坏代码的整体性,使维护变得困难。

要么把函数返回的 JSX 直接内联到组件内,要么将其拆分成一个组件。

有一点需要注意,如果你创建了一个新组件,不必将其移动到新文件中的。

如果多个组件紧密耦合,将它们保存在同一个文件中是有意义的。

state 的多个状态

避免使用多个布尔值来表示组件状态。

当编写一个组件并多次迭代后,很容易出现这样一种情况,即内部有多个布尔值来表示 该组件处于哪种状态。

比如下面的例子:

function Component() {

const [isLoading, setIsLoading] = useState(false)

const [isFinished, setIsFinished] = useState(false)

const [hasError, setHasError] = useState(false)

const fetchSomething = () => {

setIsLoading(true)

fetch(url)

.then(() => {

setIsLoading(false)

setIsFinished(true)

})

.catch(() => {

setHasError(true)

})

}

if (isLoading) return 

if (hasError) return 

if (isFinished) return 

return 

}

当按钮被点击时,我们将 isLoading 设置为 true,并通过 fetch 执行网络请求。

如果请求成功,我们将 isLoading 设置为 falseisFinished 设置为 true,如果有错误,将 hasError 设置为 true

虽然这在技术上是可行的,但很难推断出组件处于什么状态,而且不容易维护。

并且有可能最终处于“不可能的状态”,比如我们不小心同时将 isLoading 和 isFinished 设置为 true

解决此问题一劳永逸的方案是 使用枚举来管理状态。

在其他语言中,枚举是一种定义变量的方式,该变量只允许设置为预定义的常量值集合,虽然在JavaScript 中不存在枚举,但我们可以使用字符串作为枚举:

function Component() {

const [state, setState] = useState(‘idle’)

const fetchSomething = () => {

setState(‘loading’)

fetch(url)

.then(() => {

setState(‘finished’)

})

.catch(() => {

setState(‘error’)

})

}

if (state === ‘loading’) return 

if (state === ‘error’) return 

if (state === ‘finished’) return 

return 

}

通过这种方式,完全杜绝了出现 不可能状态的情况,并更利用扩展。

如果你使用 TypeScript 开发的话,则可以从定义时就实现枚举:

const [state, setState] = useState<‘idle’ | ‘loading’ | ‘error’ | ‘finished’>(‘idle’)

useState 过多

避免在同一个组件中使用太多的 useState

一个包含许多 useState 的组件可能会做多件事情,可以考虑是否要拆分它。

当然也存在一些复杂的场景,我们需要在组件中管理一些复杂的状态。

下面是自动输入组件的例子:

function AutocompleteInput() {

const [isOpen, setIsOpen] = useState(false)

const [inputValue, setInputValue] = useState(‘’)

const [items, setItems] = useState([])

const [selectedItem, setSelectedItem] = useState(null)

const [activeIndex, setActiveIndex] = useState(-1)

const reset = () => {

setIsOpen(false)

setInputValue(‘’)

setItems([])

setSelectedItem(null)

setActiveIndex(-1)

}

const selectItem = (item) => {

setIsOpen(false)

setInputValue(item.name)

setSelectedItem(item)

}

}

总结

秋招即将开始,校招的朋友普遍是缺少项目经历的,所以底层逻辑,基础知识要掌握好!

而一般的社招,更是神仙打架。特别强调,项目经历不可忽视;几乎简历上提到的项目都会被刨根问底,所以项目应用的技术要熟练,底层原理必须清楚。

这里给大家提供一份汇集各大厂面试高频核心考点前端学习资料。涵盖 HTML,CSS,JavaScript,HTTP,TCP协议,浏览器,Vue框架,算法等高频考点238道(含答案)

资料截图 :

高级前端工程师必备资料包

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
算法等高频考点238道(含答案)**!

资料截图 :

高级前端工程师必备资料包

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-99eXTn4T-1713382895608)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值