共计 6155 个字符,预计需要花费 16 分钟才能阅读完成。
redux 与 mobx 的区别?
两者对⽐:
- redux 将数据保留在单⼀的 store 中,mobx 将数据保留在扩散的多个 store 中
- redux 使⽤ plain object 保留数据,须要⼿动解决变动后的操作;mobx 适⽤ observable 保留数据,数据变动后⾃动解决响应的操作
- redux 使⽤不可变状态,这意味着状态是只读的,不能间接去批改它,⽽是应该返回⼀个新的状态,同时使⽤纯函数;mobx 中的状态是可变的,能够间接对其进⾏批改
mobx 相对来说⽐较简略,在其中有很多的形象,mobx 更多的使⽤⾯向对象的编程思维;redux 会⽐较简单,因为其中的函数式编程思维把握起来不是那么容易,同时须要借助⼀系列的中间件来解决异步和副作⽤
- mobx 中有更多的形象和封装,调试会⽐较艰难,同时后果也难以预测;⽽ redux 提供可能进⾏工夫回溯的开发⼯具,同时其纯函数以及更少的形象,让调试变得更加的容易
场景辨析:
- 基于以上区别,咱们能够简略得剖析⼀下两者的不同使⽤场景。
- mobx 更适宜数据不简单的应⽤:mobx 难以调试,很多状态⽆法回溯,⾯对复杂度⾼的应⽤时,往往⼒不从⼼。
- redux 适宜有回溯需要的应⽤:⽐如⼀个画板应⽤、⼀个表格应⽤,很多时候须要撤销、重做等操作,因为 redux 不可变的个性,人造⽀持这些操作。
- mobx 适宜短平快的项⽬:mobx 上⼿简略,样板代码少,能够很⼤水平上提⾼开发效率。
- 当然 mobx 和 redux 也并不⼀定是⾮此即彼的关系,你也能够在项⽬中⽤ redux 作为全局状态治理,⽤ mobx 作为组件部分状态管理器来⽤。
什么是 prop drilling,如何防止?
在构建 React 应用程序时,在多层嵌套组件来应用另一个嵌套组件提供的数据。最简略的办法是将一个 prop
从每个组件一层层的传递上来,从源组件传递到深层嵌套组件,这叫做 prop drilling。prop drilling
的次要毛病是本来不须要数据的组件变得不必要地简单,并且难以保护。
为了防止 prop drilling
,一种罕用的办法是应用React Context。通过定义提供数据的Provider
组件,并容许嵌套的组件通过 Consumer
组件或useContext
Hook 应用上下文数据。
这段代码有什么问题吗?
这段代码有什么问题:
this.setState((prevState, props) => {
return {streak: prevState.streak + props.count,};
});
答案:
没有什么问题。这种形式很少被应用,咱们能够将一个函数传递给setState
,该函数接管上一个 state
的值和以后的props
,并返回一个新的状态,如果咱们须要依据以前的状态从新设置状态,举荐应用这种形式。
diff 算法是怎么运作
每一种节点类型有本人的属性,也就是 prop,每次进行 diff 的时候,react 会先比拟该节点类型,如果节点类型不一样,那么 react 会间接删除该节点,而后间接创立新的节点插入到其中,如果节点类型一样,那么会比拟 prop 是否有更新,如果有 prop 不一样,那么 react 会断定该节点有更新,那么重渲染该节点,而后在对其子节点进行比拟,一层一层往下,直到没有子节点
React 的生命周期办法有哪些?
componentWillMount
: 在渲染之前执行,用于根组件中的 App 级配置。componentDidMount
:在第一次渲染之后执行,能够在这里做 AJAX 申请,DOM 的操作或状态更新以及设置事件监听器。componentWillReceiveProps
:在初始化render
的时候不会执行,它会在组件承受到新的状态 (Props) 时被触发,个别用于父组件状态更新时子组件的从新渲染shouldComponentUpdate
:确定是否更新组件。默认状况下,它返回true
。如果确定在state
或props
更新后组件不须要在从新渲染,则能够返回false
,这是一个进步性能的办法。componentWillUpdate
:在shouldComponentUpdate
返回true
确定要更新组件之前件之前执行。componentDidUpdate
:它次要用于更新 DOM 以响应props
或state
更改。componentWillUnmount
:它用于勾销任何的网络申请,或删除与组件关联的所有事件监听器。
应用 React Hooks 益处是啥?
首先,Hooks 通常反对提取和重用跨多个组件通用的有状态逻辑,而无需承当高阶组件或渲染 props
的累赘。Hooks
能够轻松地操作函数组件的状态,而不须要将它们转换为类组件。
Hooks 在类中不起作用,通过应用它们,咱们能够完全避免应用生命周期办法,例如 componentDidMount
、componentDidUpdate
、componentWillUnmount
。相同,应用像 useEffect
这样的内置钩子。
参考 前端进阶面试题具体解答
什么状况下应用异步组件
- 进步页面加载速度,应用
reloadable
把各个页面别离独自打包,按需加载
Dva 工作原理
集成
redux+redux-saga
工作原理
扭转产生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会扭转数据的时候能够通过
dispatch
发动一个action
,如果是同步行为会间接通过Reducers
扭转State
,如果是异步行为(副作用)会先触发Effects
而后流向Reducers
最终扭转State
React 中 refs 干嘛用的?
Refs
提供了一种拜访在 render
办法中创立的 DOM 节点或者 React 元素的办法。在典型的数据流中,props
是父子组件交互的惟一形式,想要批改子组件,须要应用新的 pros
从新渲染它。凡事有例外,某些状况下咱们须要在典型数据流外,强制批改子代,这个时候能够应用 Refs
。
咱们能够在组件增加一个 ref
属性来应用,该属性的值是一个回调函数,接管作为其第一个参数的底层 DOM 元素或组件的挂载实例。
class UnControlledForm extends Component {handleSubmit = () => {console.log("Input Value:", this.input.value);
};
render() {
return (<form onSubmit={this.handleSubmit}>
<input type="text" ref={(input) => (this.input = input)} />
<button type="submit">Submit</button>
</form>
);
}
}
请留神,input
元素有一个 ref
属性,它的值是一个函数。该函数接管输出的理论 DOM 元素,而后将其放在实例上,这样就能够在 handleSubmit
函数外部拜访它。
常常被误会的只有在类组件中能力应用 refs
,然而 refs
也能够通过利用 JS 中的闭包与函数组件一起应用。
function CustomForm({handleSubmit}) {
let inputElement;
return (<form onSubmit={() => handleSubmit(inputElement.value)}>
<input type="text" ref={(input) => (inputElement = input)} />
<button type="submit">Submit</button>
</form>
);
}
为什么类办法须要绑定到类实例?
在 JS 中,this
值会依据以后上下文变动。在 React 类组件办法中,开发人员通常心愿 this
援用组件的以后实例,因而有必要将这些办法绑定到实例。通常这是在构造函数中实现的:
class SubmitButton extends React.Component {constructor(props) {super(props);
this.state = {isFormSubmitted: false,};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit() {
this.setState({isFormSubmitted: true,});
}
render() {return <button onClick={this.handleSubmit}>Submit</button>;
}
}
形容 Flux 与 MVC?
传统的 MVC 模式在拆散数据 (Model)、UI(View 和逻辑(Controller) 方面工作得很好,然而 MVC 架构常常遇到两个次要问题:
数据流不够清晰 : 跨视图产生的级联更新经常会导致凌乱的事件网络,难于调试。
不足数据完整性 : 模型数据能够在任何中央产生渐变,从而在整个 UI 中产生不可预测的后果。
应用 Flux 模式的简单用户界面不再蒙受级联更新,任何给定的 React 组件都可能依据 store
提供的数据重建其状态。Flux 模式还通过限度对共享数据的间接拜访来增强数据完整性。
state 和 props 共同点和区别
共同点
- state 和 props 的扭转都会触发 render 函数(界面会产生扭转)
不同点
- props 是 readonly(只读),然而 state 是可读可写
- props 来自父组件,state 是组件外部的数据对象
如何有条件地向 React 组件增加属性?
对于某些属性,React 十分聪慧,如果传递给它的值是虚值,能够省略该属性。例如:
var InputComponent = React.createClass({render: function () {
var required = true;
var disabled = false;
return <input type="text" disabled={disabled} required={required} />;
},
});
渲染后果:
<input type="text" required>
另一种可能的办法是:
var condition = true;
var component = <div value="foo" {...(condition && { disabled: true})} />;
redux 异步中间件之间的优劣?
redux-thunk 长处:
- 体积⼩:redux-thunk 的实现⽅式很简略,只有不到 20 ⾏代码;
- 使⽤简略:redux-thunk 没有引⼊像 redux-saga 或者 redux-observable 额定的范式,上⼿简略。
redux-thunk 缺点:
- 样板代码过多:与 redux 自身⼀样,通常⼀个申请须要⼤量的代码,⽽且很多都是反复性质的;
- 耦合重大:异步操作与 redux 的 action 偶合在⼀起,不⽅便治理;
- 性能孱弱:有⼀些理论开发中常⽤的性能须要⾃⼰进⾏封装。
redux-saga 长处:
- 异步解耦:异步操作被被转移到独自 saga.js 中,不再是掺杂在 action.js 或 component.js 中;
- action 解脱 thunk function: dispatch 的参数仍然是⼀个纯正的 action (FSA),⽽不是充斥“⿊魔法”thunk function;
- 异样解决:受害于 generator function 的 saga 实现,代码异样 / 申请失败都能够间接通过 try/catch 语法间接捕捉解决;
- 性能强⼤:redux-saga 提供了⼤量的 Saga 辅助函数和 Effect 创立器供开发者使⽤,开发者⽆须封装或者简略封装即可使⽤;
- 灵便:redux-saga 能够将多个 Saga 能够串⾏ / 并⾏组合起来,造成⼀个⾮常实⽤的异步 flow;
- 易测试,提供了各种 case 的测试⽅案,包含 mock task,分⽀笼罩等等。
redux-saga 缺点:
- 额定的学习老本:redux-saga 不仅在使⽤难以了解的 generator function,⽽且无数⼗个 API,学习老本远超 reduxthunk,最重要的是你的额定学习老本是只服务于这个库的,与 redux-observable 不同,redux-observable 尽管也有额定学习老本然而背地是 rxjs 和⼀整套思维;
- 体积庞⼤:体积略⼤,代码近 2000 ⾏,min 版 25KB 左右;
- 性能过剩:实际上并发管制等性能很难⽤到,然而咱们仍然须要引⼊这些代码;
- ts ⽀持不敌对:yield ⽆法返回 TS 类型。
redux-observable 长处:
- 性能最强:因为背靠 rxjs 这个强⼤的响应式编程的库,借助 rxjs 的操作符,你能够⼏乎做任何你能想到的异步解决;
- 背靠 rxjs:因为有 rxjs 的加持,如果你曾经学习了 rxjs,redux-observable 的学习老本并不⾼,⽽且随着 rxjs 的降级 reduxobservable 也会变得更强⼤。
redux-observable 缺点:
- 学习老本奇⾼:如果你不会 rxjs,则须要额定学习两个简单的库;
- 社区⼀般:redux-observable 的下载量只有 redux-saga 的 1 /5,社区也不够沉闷,在简单异步流中间件这个层⾯ reduxsaga 仍处于领导位置。
react 的全家桶有哪些
- react:外围
-
redux:相当于数据,次要存储数据状态
react-redux 能够实现数据订阅
redux-thunk 能够实现异步的 action
redux-logger 是 redux 的日志中间件
react-router 专门为 react 提供路由解决方案,它利用 HTML5 的 history API,来操作浏览器的 session history (会话历史)
-
react-router:提供外围的路由组件与函数
react-router-config:用来配置动态路由(还在开发中)
react-router-native:
react-router-dom:
- axios:是基于 promise 的用于浏览器和服务端进行数据交互的技术
- antd:Ant Degisn 是个很好的 React UI 库
React 性能优化
- shouldCompoentUpdate
- pureComponent 自带 shouldCompoentUpdate 的浅比拟优化
- 联合 Immutable.js 达到最优
如何通知 React 它应该编译生产环境版
通常状况下咱们会应用
Webpack
的DefinePlugin
办法来将NODE_ENV
变量值设置为production
。编译版本中React
会疏忽propType
验证以及其余的告警信息,同时还会升高代码库的大小,React
应用了Uglify
插件来移除生产环境下不必要的正文等信息
React- Router 有几种模式?
有以下几种模式。
HashRouter,通过散列实现,路由要带 #。
BrowerRouter,利用 HTML5 中 history API 实现,须要服务器端反对,兼容性不是很好。
react-router4 的外围
- 路由变成了组件
- 扩散到各个页面,不须要配置 比方
<link> <route></route>
简述 flux 思维
Flux
的最大特点,就是数据的 ” 单向流动 ”。
- 用户拜访
View
View
收回用户的Action
Dispatcher
收到Action
,要求Store
进行相应的更新Store
更新后,收回一个"change"
事件View
收到"change"
事件后,更新页面