说说对React的理解?有哪些特性?
React,用于构建用户界面的 JavaScript 库,遵循组件设计模式、类式编程和函数式编程概念,使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面.
特性
- JSX语法
- 组件化开发
- 虚拟DOM
- 单向绑定
- 声明式编程
优势
- 声明式编程,简单使用
- 组件化开发,提高代码复用率
- 单向绑定,数据更安全,速度更快
什么是JSX和它的特性?
JSX 是JavaScript XML的缩写,不是html或xml,基于ECMAScript的一种新特性,一种定义带属性树结构的语法;
特性:
- 自定义组件名首字母大写
- 嵌套;在render函数中return返回的只能包含一个顶层标签,否则也会报错。
- 求值表达式;JSX基本语法规则,遇到HTML标签(以<开头),就用HTML规则解析;遇到代码块(以{开头),就用JS规则解析
- 驼峰命名
- class属性需要写成className
- JSX允许直接在模板插入JS变量。如果这个变量是一个数组,则会展开这个数组的所有成员
- 在JSX中插入用户输入是安全的,默认情况下ReactDOM会在渲染前,转义JSX中的任意值,渲染前,所有的值都被转化为字符串形式,这能预防XSS攻击。
类组件和函数组件之间有什么区别?
类组件:
- this指向它的实例
- 类组件有三大属性:props,state,ref
- 属性 props是外界传递过来的,不能修改它自己的 props。
- 状态 state是组件本身的,状态可以在组件中任意修改
- React 组件都必须是纯函数
- React是单项数据流,父组件改变了属性,那么子组件视图会更新。
纯函数:一个函数的返回结果只依赖其参数,并且执行过程中没有副作用。
函数组件:
- this指向的是undefined
- Hook是React的新特性,分别是:useState、useEffect、useRef
- 函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可
说说对React Hooks的理解?解决了什么问题?
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性,因此,现在的函数组件也可以是有状态的组件,内部也可以维护自身的状态以及做一些逻辑方面的处理;
最常见的hooks有:
useState:声明和修改变量
useEffect:生命周期,可以做初始化请求和收尾工作
useRef:操作dom
hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能;
说说对 State 和 Props的理解,有什么区别?
State
- 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state,一般在 constructor 中初始化
- 当需要修改里面的值的状态需要通过调用setState来改变,从而达到更新组件内部数据的作用,并且重新调用组件render方法
- setState还可以接受第二个参数,它是一个函数,会在setState调用完成并且组件开始重新渲染时被调用,可以用来监听渲染是否完成
Props
- React的核心思想就是组件化思想,页面会被切分成一些独立的、可复用的组件,组件从概念上看就是一个函数,可以接受一个参数作为输入值,这个参数就是props,所以可以把props理解为从外部传入组件内部的数据
- react具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据
- props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数
- 在子组件中,props在内部不可变的,如果想要改变它看,只能通过外部组件传入新的props来重新渲染子组件,否则子组件的props和展示形式不会改变
相同点
- 两者都是 JavaScript 对象
- 两者都是用于保存信息
- props 和 state 都能触发渲染更新
区别
- props 是外部传递给组件的,而 state 是在组件内被组件自己管理的,一般在 constructor 中初始化
- props 在组件内部是不可修改的,但 state 在组件内部可以进行修改
- state 是多变的、可以修改
说说对React refs 的理解?应用场景?
React 中的 Refs提供了一种方式,允许我们访问 DOM节点或在 render方法中创建的 React元素。
本质为ReactDOM.render()返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom则返回的是具体的dom节点。
如何使用
- 传入字符串,使用时通过 this.refs.传入的字符串的格式获取对应的元素
- 传入对象,对象是通过 React.createRef() 方式创建出来,使用时获取到创建的对象中存在 current 属性就是对应的元素
- 传入函数,该函数会在 DOM 被挂载时进行回调,这个函数会传入一个 元素对象,可以自己保存,使用时,直接拿到之前保存的元素对象即可
- 传入hook,hook是通过 useRef() 方式创建,使用时通过生成hook对象的 current 属性就是对应的元素
应用场景
在某些情况下,我们会通过使用refs来更新组件,但这种方式并不推荐,过多使用refs,会使组件的实例或者是DOM结构暴露,违反组件封装的原则;
但下面的场景使用refs非常有用:
- 对Dom元素的焦点控制、内容选择、控制
- 对Dom元素的内容设置及媒体播放
- 对Dom元素的操作和对组件实例的操作
- 集成第三方 DOM 库
setState是同步还是异步
- setState处于同步的逻辑中,异步更新状态
- setState处于异步的逻辑中,同步更新状态
- setState接收第二个参数,第二个参数是一个回调函数
React组件生命周期有几个阶段
初始渲染阶段:这是组件即将开始其生命之旅并进入 DOM 的阶段。
- getDefaultProps:获取实例的默认属性
- getInitialState:获取每个实例的初始化状态
- componentWillMount:组件即将被装载、渲染到页面上
- render:组件在这里生成虚拟的 DOM 节点
- componentDidMount:组件真正在被装载之后
更新阶段:一旦组件被添加到 DOM,它只有在 prop 或状态发生变化时才可能更新和重新渲染。这些只发生在这个阶段。
- componentWillReceiveProps:组件将要接收到属性的时候调用
- shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
- componentWillUpdate:组件即将更新不能修改属性和状态
- render:组件重新描绘
- componentDidUpdate:组件已经更新
卸载阶段:这是组件生命周期的最后阶段,组件被销毁并从 DOM 中删除。
- componentWillUnmount:组件即将销毁
受控组件和非受控组件的区别
受控组件是React控制的组件,input等表单输入框值不存在于 DOM 中,而是以我们的组件状态存在。每当我们想要更新值时,我们就像以前一样调用setState。
不受控制组件是您的表单数据由 DOM 处理,而不是React 组件,Refs 用于获取其当前值;
react组件之间如何通信
- 父子:父传子:props; 子传父:子调用父组件中的函数并传参;
- 兄弟:利用redux实现和利用父组件
- 所有关系都通用的方法:利用PubSub.js订阅
说说react中引入css的方式有哪几种?区别?
在组件内直接使用
- 组件中引入 .css 文件
- 组件中引入 .module.css 文件
- CSS in JS
- 点击 react中引入css的方式查看以上几种引入方式的代码案例
区别
- 在组件内直接使用css该方式编写方便,容易能够根据状态修改样式属性,但是大量的演示编写容易导致代码混乱
- 组件中引入 .css 文件符合我们日常的编写习惯,但是作用域是全局的,样式之间会层叠
- 引入.module.css 文件能够解决局部作用域问题,但是不方便动态修改样式,需要使用内联的方式进行样式的编写
- 通过css in js 这种方法,可以满足大部分场景的应用,可以类似于预处理器一样样式嵌套、定义、修改状态等
- 至于使用react用哪种方案引入css,并没有一个绝对的答案,可以根据各自情况选择合适的方案
React context是什么?
当你不想在组件树中通过逐层传递props或者state的方式来传递数据时,可以使用Context来实现跨层级的组件数据传递。
说说你对Redux的理解?其工作原理?
redux将所有的状态进行集中管理,当需要更新状态的时候,仅需要对这个管理集中处理,而不用去关心状态是如何分发到每一个组件内部的,redux是一个实现集中管理的容器,遵循三大基本原则:单一数据源、state 是只读的、使用纯函数来执行修改;
注意的是,redux并不是只应用在react中,还与其他界面库一起使用,如Vue;
工作原理
redux要求我们把数据都放在 store公共存储空间,一个组件改变了 store 里的数据内容,其他组件就能感知到 store的变化,再来取数据,从而间接的实现了这些数据传递的功能
Redux遵循的三个原则是什么?
- 单一事实来源:整个应用的状态存储在单个 store 中的对象/状态树里。单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序。
- 状态是只读的:改变状态的唯一方法是去触发一个动作。动作是描述变化的普通 JS 对象。就像 state 是数据的最小表示一样,该操作是对数据更改的最小表示。
- 使用纯函数进行更改:为了指定状态树如何通过操作进行转换,你需要纯函数。纯函数是那些返回值仅取决于其参数值的函数。