react常见问题整理(一)

第一部分:react部分
1.react中不同组件之间如何做到数据交互?组件通信
2.react生命周期函数?
3.react性能优化是哪个周期函数?
4.react中 虚拟 dom 会提高性能?
5.react中 diff 算法原理?
6.react中refs的作用是什么?
7.react中key的作用是什么?
8.React组件中props和state有什么区别?
9.react中setstate之后做了什么?
10.高阶组件(higher order component)
11.react性能优化方案
12.redux介绍一下?
13.redux的缺点?
14.redux中间件?
15.react中组件分为那俩种?
16.react中函数组件和普通组件的区别?
17.react中如何打包上传图片文件?
18.react 按需加载?
19.react-router?
以下未整理:
20.列举重新渲染render的情况
21.组件绑定和js原生绑定事件哪个先执行
22.fetch的延时操作
23.A 组件嵌套 B 组件,生命周期执行顺序
24.新出来两个钩子函数?和砍掉的will系列有啥区别?
25.对单向数据流和双向数据绑定的理解,好处?
26.redux本来是同步的为什么它能执行异步代码(chunk)实现原理是什么 中间件的实现原理是什么
27.
React
一、 有了解过React.js吗?
React.js 只是一个视图库
(1)声明式设计
(2)高效:通过对DOM的模拟,最大限度的减少与DOM的交互。
(3)灵活:可以与已知的框架或库很好的配合。
(4)JSX:是js语法的扩展,不一定使用,但建议用。
(5)组件:构建组件,使代码更容易得到复用,能够很好地应用在大项目的开发中。
(6)单向响应的数据流:React实现了单向响应的数据流,从而减少了重复代码,这也是解释了它为什么比传统数据绑定更简单。
1
####组件通信
父子
父->子 props 通过ref进行标记 就可以将子组件的方法挂载到父组件上 调用子组件的更改方法
子->父 子组件通过props 获得父组件的修改方法 调用父组件的更改方法 类似于自定义事件
兄弟
亲兄弟 进行结合
1.子组件a调用父组件的方法修改父组件的state 子组件2通过props 获取父组件修改的状态值
2.子组件a调用父组件的方法 子组件b通过ref 将修改自己state的方法挂载父组件上 由 子组件a进行调用
2
? 初始化阶段:
? getDefaultProps:获取实例的默认属性
? getInitialState:获取每个实例的初始化状态
? componentWillMount:组件即将被装载、渲染到页面上
? render:组件在这里生成虚拟的 DOM 节点
? componentDidMount:组件真正在被装载之后
? 运行中状态:
? componentWillReceiveProps:组件将要接收到属性的时候调用
? shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
? componentWillUpdate:组件即将更新不能修改属性和状态
? render:组件重新描绘
? componentDidUpdate:组件已经更新
? 销毁阶段:
? componentWillUnmount:组件即将销毁
?
3.
shouldComponentUpdate这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能,如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能。

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
5.
? 把树形结构按照层级分解,只比较同级元素。
? 给列表结构的每个单元添加唯一的 key 属性,方便比较。
? React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
? 合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
? 选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。
6.
Refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。我们可以为元素添加 ref 属性然后在回调函数中接受该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回:
class CustomForm extends Component {
handleSubmit = () => {
console.log("Input Value: ", this.input.value)
}
render () {
return (

type=‘text’
ref={(input) => this.input = input} />
Submit

)
}
}
上述代码中的 input 域包含了一个 ref 属性,该属性声明的回调函数会接收 input 对应的 DOM 元素,我们将其绑定到 this 指针以便在其他的类函数中使用。另外值得一提的是,refs 并不是类组件的专属,函数式组件同样能够利用闭包暂存其值:
function CustomForm ({handleSubmit}) {
let inputElement
return (
handleSubmit(inputElement.value)}>
type=‘text’
ref={(input) => inputElement = input} />
Submit

)
}
Keys 是 React 用于追踪哪些列表中元素,被修改、被添加或者被移除的辅助标识。
render () {
return (


    {this.state.todoItems.map(({item, key}) => {
    return
  • {item}

  • })}

)
}
在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。
8.
? State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
? Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递。 【react常见问题整理(一)】
在代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC。
11.
  1. 重写shouldComponentUpdate来避免不必要的dom操作0
  2. 使用 production 版本的react.js0
  3. 使用key来帮助React识别列表中所有子组件的最小变化。
? redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer,工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 getState 获取最新的数据,
? flux 也是用来进行数据操作的,有四个组成部分 action,dispatch,view,store,工作流程是 view 发出一个 action,派发器接收 action,让 store 进行数据更新,更新完成以后 store 发出 change,view 接受 change 更新视图。Redux 和 Flux 很像。主要区别在于 Flux 有多个可以改变应用状态的 store,在 Flux 中 dispatcher 被用来传递数据到注册的回调事件,但是在 redux 中只能定义一个可更新状态的 store,redux 把 store 和 Dispatcher 合并,结构更加简单清晰
? 新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
? 一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
? 当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。
14.
中间件提供第三方插件的模式,自定义拦截action一> reducer的过程。变为action一〉 middlewares 一> reducer。这种机制可以让我们改变数据流,实现如异步action, action过滤,日志输出,异常报告等功能。
常见的中间件:
redux一logger:提供日志输出
redux一thunk:处理异步操作
redux一promise:处理异步操作,actionCreator的返回值是promise
根据组件的职责通常把组件分为UI组件和容器组件。
UI组件负责UI的呈现,容器组件负责管理数据和逻辑。
两者通过React一Redux提供connect方法联系起来。
? 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
? 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件(stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件
17.
为了处理图片上传,我用了 react-dropzone 插件。它包含了一些功能,如拖放文件、文件类型限制和多文件上传。
首先,安装依赖。在命令行中输入下面的命令,运行:
  1. npm install react react-dropzone superagent --save
    然后在你的组件中导入 React、 react-dropzone 和 superagent。
Router就是React的一个组件,它并不会被渲染,只是一个创建内部路由规则的配置对象,根据匹配的路由地址展现相应的组件。Route则对路由地址和组件进行绑定,Route具有嵌套功能,表示路由地址的包涵关系,这和组件之间的嵌套并没有直接联系。Route可以向绑定的组件传递7个属性:children,history,location,params,route,routeParams,routes,每个属性都包涵路由的相关的信息。比较常用的有children(以路由的包涵关系为区分的组件),location(包括地址,参数,地址切换方式,key值,hash值)。react-router提供Link标签,这只是对a标签的封装,值得注意的是,点击链接进行的跳转并不是默认的方式,react-router阻止了a标签的默认行为并用pushState进行hash值的转变。切换页面的过程是在点击Link标签或者后退前进按钮时,会先发生url地址的转变,Router监听到地址的改变根据Route的path属性匹配到对应的组件,将state值改成对应的组件并调用setState触发render函数重新渲染dom。
当页面比较多时,项目就会变得越来越大,尤其对于单页面应用来说,初次渲染的速度就会很慢,这时候就需要按需加载,只有切换到页面的时候才去加载对应的js文件。react配合webpack进行按需加载的方法很简单,Route的component改为getComponent,组件用require.ensure的方式获取,并在webpack中配置chunkFilename
展示组件(Presentational component)和容器组件(Container component)之间有何不同
? 展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。
? 容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源。
类组件(Class component)和函数式组件(Functional component)之间有何不同
? 类组件不仅允许你使用更多额外的功能,如组件自身的状态和生命周期钩子,也能使组件直接访问 store 并维持状态
? 当组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件(stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件
何为受控组件(controlled component)
在 HTML 中,类似 , 和 这样的表单元素会维护自身的状态,并基于用户的输入来更新。当用户提交表单时,前面提到的元素的值将随表单一起被发送。但在 React 中会有些不同,包含表单元素的组件将会在 state 中追踪输入的值,并且每次调用回调函数时,如 onChange 会更新 state,重新渲染组件。一个输入表单元素,它的值通过 React 的这种方式来控制,这样的元素就被称为"受控元素"。
为什么建议传递给 setState 的参数是一个 callback 而不是一个对象
因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。
除了在构造函数中绑定 this,还有其它方式吗
你可以使用属性初始值设定项(property initializers)来正确绑定回调,create-react-app 也是默认支持的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。
(在构造函数中)调用 super(props) 的目的是什么
在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。
应该在 React 组件的何处发起 Ajax 请求
在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络请求将保证这有一个组件可以更新了。
描述事件在 React 中的处理方式。
为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent 的实例,它是 React 的浏览器本机事件的跨浏览器包装器。
这些 SyntheticEvent 与您习惯的原生事件具有相同的接口,除了它们在所有浏览器中都兼容。有趣的是,React 实际上并没有将事件附加到子节点本身。React 将使用单个事件监听器监听顶层的所有事件。这对于性能是有好处的,这也意味着在更新 DOM 时,React 不需要担心跟踪事件监听器。
createElement 和 cloneElement 有什么区别?
React.createElement():JSX 语法就是用 React.createElement()来构建 React 元素的。它接受三个参数,第一个参数可以是一个标签名。如 div、span,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。
React.createElement(
type,
[props],
[…children]
)
React.cloneElement()与 React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而就的子元素奖杯替换。
React.cloneElement(
element,
[props],
[…children]
)
React 中有三种构建组件的方式
React.createClass()、ES6 class 和无状态函数。
react 组件的划分业务组件技术组件?
? 根据组件的职责通常把组件分为 UI 组件和容器组件。
? UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
? 两者通过 React-Redux 提供 connect 方法联系起来。
简述 flux 思想
Flux 的最大特点,就是数据的"单向流动"。
  1. 用户访问 View
  2. View 发出用户的 Action
  3. Dispatcher 收到 Action,要求 Store 进行相应的更新
  4. Store 更新后,发出一个"change"事件
  5. View 收到"change"事件后,更新页面

    推荐阅读