React组件渲染两次
在开发一个新项目的过程中,发现react会重复挂载一次,导致相同的接口调用了两次。查阅资料发现了问题出在了使用create-react-app
创建的项目中使用了React.StrictMode
, 如何找问题的过程就不再赘述,无非是百度谷歌一起上。
着重讲一下React.StrictMode
的作用,以及为什么会使组件重新挂载。
什么是React.StrictMode?
React.StrictMode
是在2018年的16.3.0版本中引入的组件,一开始它只用在类组件中,而在16.8.0中,它对hook同样使用。
看官方文档可知,React.StrictMode
是帮助我们在开发的时候帮助我们找到不纯粹的组件,这是基于在React假设你编写的所有组件都是纯函数的前提下做出的判断。
简单来说就是React认为,组件应该仅依赖Props, State, Context数据来实现组件的渲染,而不依赖于除上述数据之外的数据,例如函数组件之外的一个闭包自增变量。在相同的入参的前提下,多次调用这个组件应当产生同一个JSX。
而显而易见的,React.StrictMode
会重复挂载组件必然不会在生产环境出现,所以实际上也只有开发环境会其作用。
React 为何侧重纯函数?
- 组件可以在不同的环境下运行,例如在服务器上!由于它们针对相同的输入,总是返回相同的结果,因此一个组件完全可以在各端复用满足不同用户的请求,也便于实现组件的缓存。
- 可以为那些输入未更改的组件跳过渲染,以提高性能,因为只要判断输入是相同的,就知道输出是相同的,所以不需要多余的无效渲染
- 可以随时重新渲染,当次被放弃的渲染不会影响下次渲染。
END
- 一个组件必须是纯粹的,这就意味着:
- 只负责自己的任务,不会更改在该函数调用前就已经存在的变量
- 输入相同,则输出相同
- 渲染随时可能发生,因此组件不应依赖于彼此的渲染顺序
- 不应该改变组件用于渲染的任何输入,包括props,state,context。通过set state来更新界面,不要改变预先存在的对象
- 努力在返回的JSX中表达组件的逻辑,当需要“改变事物”时,你通常希望在事件处理程序中进行。作为最后的手段,可以使用
useEffect
- 编写纯函数需要一些联系,但它充分释放了React范式的能力