学习React与Next.js过程中的疑惑
- 1、为什么React中函数作为props的时候,会出现无限调用的情况,而把函数放在箭头函数中就可以解决呢?
- 2、next.js与node.js有什么区别?
- 3、什么是快速刷新?
- 4、Hooks出现的原因是什么,诞生是为了解决什么问题?
- 5、什么是Hooks?
- 6、在学习两种props传值:
- 7、为什么forEach可以在返回的时候写{}而map不可以写{}?
- 八、如何理解React中的状态快照?
- 九、什么是“批处理”
- 十、传递下一次状态 和 传递 程序处理函数 的区别
- 十一、在React中对多个字段使用单个事件处理程序
- 关于渲染列表时,使用map,我最容易犯的错误:
- 1、传参忘记解构
- 2、map返回的时候写了{}忘记写返回值。
- 3、return忘记写();
1、为什么React中函数作为props的时候,会出现无限调用的情况,而把函数放在箭头函数中就可以解决呢?
chatgpt的回答:
在 React 中,当函数作为 props 传递给子组件时,如果该函数在子组件中被调用并返回一个新的值,会触发子组件的重新渲染,这会导致组件树中的其他组件也被重新渲染,从而引起性能问题。
这种无限调用的情况通常是由于传递给子组件的函数依赖于父组件的状态或属性,当父组件状态或属性发生变化时,传递给子组件的函数会重新计算,并触发子组件重新渲染,从而形成无限循环的现象。
为了避免这种情况,可以将函数包装在箭头函数中,这样在组件重新渲染时,父组件传递给子组件的箭头函数引用不会改变,从而避免了触发子组件的重新渲染。箭头函数是一种匿名函数,它的上下文是被定义时所在的作用域,而不是执行时的作用域,这就保证了函数的引用在组件重新渲染时不会改变。
需要注意的是,如果函数作为 props 传递给子组件的时候需要依赖父组件的状态或属性,可以考虑使用 React.memo 或 shouldComponentUpdate 方法对组件进行优化,从而避免不必要的渲染。同时,也可以使用 useCallback 或 useMemo 来缓存函数的引用,从而避免在组件重新渲染时重新计算函数。
2、next.js与node.js有什么区别?
Next.js 和 Node.js 是两个不同的概念和技术,它们具有不同的作用和用途。
Next.js 是一个基于 React 的应用程序框架,它提供了一系列的开箱即用的特性,例如服务器渲染、静态生成、自动代码分割、CSS-in-JS、路由等等。使用 Next.js,开发者可以快速搭建 React 应用程序,并通过一些内置的功能轻松实现 SEO 优化、性能优化等需求。Next.js 的底层是基于 Node.js 的,但它主要用于构建 Web 应用程序,而不是编写服务器端应用程序。
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它使开发者可以使用 JavaScript 在服务器端构建高性能、可伸缩的应用程序。Node.js 提供了一些内置的模块和 API,例如文件系统、网络通信、加密、数据库访问等等,同时也有大量的第三方库和模块可以使用。Node.js 通常被用于构建服务器端应用程序、命令行工具、网络工具、物联网应用等等。
总之,Next.js 是一个基于 React 的应用程序框架,用于构建 Web 应用程序,而 Node.js 是一个 JavaScript 运行时,用于在服务器端构建应用程序。两者虽然底层都是基于 JavaScript,但用途和作用是不同的。
3、什么是快速刷新?
next.js提供了快速刷新的功能,我很疑惑:快速刷新什么?
Next.js 开发服务器启用了快速刷新。当您对文件进行更改时,Next.js 几乎立即自动在浏览器中应用更改。无需刷新!这将帮助您快速迭代您的应用程序。
4、Hooks出现的原因是什么,诞生是为了解决什么问题?
React中的Hooks是为了解决在组件中共享状态逻辑的问题,以及使得组件代码更加复用和易于测试。
在React早期的版本中,组件之间共享状态逻辑通常需要使用高阶组件(Higher Order Component)或者渲染属性(Render Props)等技术来实现。但这些方法都存在一些问题,比如难以理解、使用起来繁琐、代码复杂度高等。
Hooks的诞生为React组件的状态管理提供了一种新的方式,使得开发者可以通过一些特定的函数来管理组件的状态,并且可以在不同的组件之间共享这些状态逻辑。此外,Hooks也可以帮助开发者更好地处理副作用(如网络请求、订阅等),从而使得组件代码更加简洁易读。
总之,Hooks的出现为React开发提供了一种新的方式来管理组件状态和副作用,使得代码更加易于理解、复用和维护。
5、什么是Hooks?
Hook是React 16.8版本引入的一种特性,它是一些特殊的函数,可以让开发者在函数式组件中使用 React 的一些特性,如状态(state)、生命周期函数(lifecycle)、上下文(context)和副作用(effects)等。在React中,Hook可以帮助开发者将组件的状态和逻辑更好地组织和管理,从而使组件的代码更加简洁、易于理解和维护。
Hook有两种类型:
State Hook: useState
useState用于在函数式组件中添加局部状态。它返回一个数组,第一个值是当前状态值,第二个值是更新该状态值的函数。
Effect Hook: useEffect, useLayoutEffect, useImperativeHandle, useMutationEffect, useInsertionEffect
useEffect用于在函数式组件中处理副作用,比如网络请求、订阅、定时器等。它可以模拟类组件的生命周期函数,包括componentDidMount、componentDidUpdate、componentWillUnmount。
useLayoutEffect类似于useEffect,但它会在浏览器绘制之前同步执行。useLayoutEffect可以在DOM更新之后立即同步执行一些代码,因此可以用来处理某些需要在DOM更新之后才能获取正确尺寸和位置的任务。
除此之外,还有一些其他的Hook可以帮助开发者在函数式组件中使用 React 的其他特性,比如 useContext、useReducer、useCallback、useMemo、useRef等。
总的来说,使用Hook可以让函数式组件具有类似于类组件的能力,从而更好地组织和管理组件状态和逻辑。
6、在学习两种props传值:
第一种:通过参数传值,可以通过属性传递参数,组件可以写成单个的形式:<Card/>
第二种:直接传递jsx的children,这种数据直接写在标签里面写死,一起传递,并且父组件要写成 一对标签且有闭合 的形式:<Card></Card>
小错误1:写一对标签且有闭合 的形式:<Card></Card>
,我还出了点小错误,我把闭合标签写成了<Card/>
小错误2:function Card({children}){}
子组件Card,里面要接收jsx的children还是要使用解构赋值的方法,而我却以为不需要再进行解构了,直接用children
接收参数,这样是不对的,要用{children}
7、为什么forEach可以在返回的时候写{}而map不可以写{}?
引申出forEach和map的不同–forEach是没有返回值的,但是map有返回值,所以map后面写小括号(),这样就算是简写了,不用写return,其实是隐式return,如果map后面写大括号{},那么就需要显式写return了。forEach没有返回值,所以不要写成小括号(),因为小括号()会隐式return,那还是return了,就会报错,所以用forEach啊,一定要写{}大括号,并且大括号{}里面不要写return。
引申出条件语句不熟悉,尤其是三元表达式与&&混用了
我当时写了这么一个东西:这肯定错了:我当时以为先判断{i>0}如果为true在执行后面的{hr什么的},但是这句话的意思是,渲染{i>0},并且渲染{hr什么的}。
要想表达我的想法,应该使用:红框上面的&&语句
我这个错误有点三元表达式与&&混用了的意思
我是与下面的这个正确用法搞混了:
这句话的意思是:先渲染name,再判断isPacked为true吗?是的话渲染对勾,不是的话渲染叉叉
key只需要在最外一层标签上使用就可以了
这里用到Fragment的显式写法,因为只能返回一个对象,如果不写Fragment就会返回两个对象:一个hr一个p标签对象。会报错,所以用Fragment标签包裹起来,就成了一个标签对象返回。开头还要from react引入Fragment标签
需要注意的是:如果有并列的多个外层标签,那么每个标签上都要加上key,比如下面的:
挖一个坑,这里的扩展运算符用的非常巧妙,待会儿回来写分析:
八、如何理解React中的状态快照?
在 React 中,组件状态的行为确实更像是一个快照,而不是一个普通的 JavaScript 变量。当您调用 setState 方法来更新组件状态时,React 并不会直接修改当前的状态变量,而是会创建一个新的状态对象,其中包含了新的状态值。然后,React 会比较新的状态对象和旧的状态对象,找出两者之间的差异,并且只更新需要更新的部分。最终,React 会重新渲染组件,并且使用新的状态对象来更新组件的显示内容。
这种设计使得 React 组件能够高效地更新显示内容,并且避免了许多手动操作,从而提高了开发效率和代码的可维护性。同时,这种设计也使得组件状态的变化变得可预测和可控,从而避免了许多常见的程序错误。
九、什么是“批处理”
在 React 中,批处理(Batching)是指将多个状态更新操作合并为一次更新的过程。当我们在调用 setState 方法来更新组件状态时,React 并不会立即更新状态,而是将更新操作放入一个更新队列中。在一些情况下,React 会将多个更新操作合并为一次更新,从而避免了不必要的重复渲染和性能损失。
下面是一些触发批处理的情况:
- 在事件处理函数中连续调用多次 setState 方法,React 会将这些更新操作合并为一次更新。
- 在 componentDidMount 和 componentDidUpdate 生命周期中调用 setState 方法,React 会将这些更新操作合并为一次更新。
- 在 setState 方法的回调函数中调用 setState 方法,React 会将这些更新操作合并为一次更新。
- 在使用 React Hooks 时,多个 useState 调用会被合并为一次更新。
需要注意的是,React 并不总是进行批处理。在某些情况下,例如在定时器或异步代码中调用 setState 方法时,React 会立即更新状态,并且不会进行批处理。因此,在编写代码时需要注意避免出现这种情况,从而保证组件状态的正确性和性能优化。
十、传递下一次状态 和 传递 程序处理函数 的区别
传递下一次状态:替换行为
程序处理函数:将原来的状态拿出来做运算,再替换的行为
您可能已经注意到它setState(5)实际上像 一样工作setState(n => 5),但n未被使用!
十一、在React中对多个字段使用单个事件处理程序
这里,e.target.name
指的是name
赋予<input>
DOM 元素的属性。
关于渲染列表时,使用map,我最容易犯的错误:
1、传参忘记解构
2、map返回的时候写了{}忘记写返回值。
map是有返回值的,如果不隐式返回,就要写return ,不写{}就是隐式返回,写了{}就要自己写return