襄阳谷城网站建设,网站建设及运行情况介绍,如何建立一个网站根目录,如何优化网站推广解释 React 中 render() 的目的。
每个React组件强制要求必须有一个 render()。它返回一个 React 元素#xff0c;是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素#xff0c;则必须将它们组合在一个封闭标记内#xff0c;例如 form、group、div是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素则必须将它们组合在一个封闭标记内例如 form、group、div 等。此函数必须保持纯净即必须每次调用时都返回相同的结果。
React中constructor和getInitialState的区别?
两者都是用来初始化state的。前者是ES6中的语法后者是ES5中的语法新版本的React中已经废弃了该方法。
getInitialState是ES5中的方法如果使用createClass方法创建一个Component组件可以自动调用它的getInitialState方法来获取初始化的State对象
var APP React.creatClass ({getInitialState() {return { userName: hi,userId: 0};}
})
React在ES6的实现中去掉了getInitialState这个hook函数规定state在constructor中实现如下
Class App extends React.Component{constructor(props){super(props);this.state{};}}
对React-Fiber的理解它解决了什么问题
React V15 在渲染时会递归比对 VirtualDOM 树找出需要变动的节点然后同步更新它们 一气呵成。这个过程期间 React 会占据浏览器资源这会导致用户触发的事件得不到响应并且会导致掉帧导致用户感觉到卡顿。
为了给用户制造一种应用很快的“假象”不能让一个任务长期霸占着资源。 可以将浏览器的渲染、布局、绘制、资源加载(例如 HTML 解析)、事件响应、脚本执行视作操作系统的“进程”需要通过某些调度策略合理地分配 CPU 资源从而提高浏览器的用户响应速率, 同时兼顾任务执行效率。
所以 React 通过Fiber 架构让这个执行过程变成可被中断。“适时”地让出 CPU 执行权除了可以让浏览器及时地响应用户的交互还有其他好处:
分批延时对DOM进行操作避免一次性操作大量 DOM 节点可以得到更好的用户体验给浏览器一点喘息的机会它会对代码进行编译优化JIT及进行热代码优化或者对 reflow 进行修正。
核心思想: Fiber 也称协程或者纤程。它和线程并不一样协程本身是没有并发或者并行能力的需要配合线程它只是一种控制流程的让出机制。让出 CPU 的执行权让 CPU 能在这段时间执行其他的操作。渲染的过程可以被中断可以将控制权交回浏览器让位给高优先级的任务浏览器空闲后再恢复渲染。
在 React 中何为 state
State 和 props 类似但它是私有的并且完全由组件自身控制。State 本质上是一个持有数据并决定组件如何渲染的对象。
React.Component 和 React.PureComponent 的区别
PureComponent表示一个纯组件可以用来优化React程序减少render函数执行的次数从而提高组件的性能。
在React中当prop或者state发生变化时可以通过在shouldComponentUpdate生命周期函数中执行return false来阻止页面的更新从而减少不必要的render执行。React.PureComponent会自动执行 shouldComponentUpdate。
不过pureComponent中的 shouldComponentUpdate() 进行的是浅比较也就是说如果是引用数据类型的数据只会比较不是同一个地址而不会比较这个地址里面的数据是否一致。浅比较会忽略属性和或状态突变情况其实也就是数据引用指针没有变化而数据发生改变的时候render是不会执行的。如果需要重新渲染那么就需要重新开辟空间引用数据。PureComponent一般会用在一些纯展示组件上。
使用pureComponent的好处当组件更新时如果组件的props或者state都没有改变render函数就不会触发。省去虚拟DOM的生成和对比过程达到提升性能的目的。这是因为react自动做了一层浅比较。
除了在构造函数中绑定 this还有其它方式吗
你可以使用属性初始值设定项(property initializers)来正确绑定回调create-react-app 也是默认支持的。在回调中你可以使用箭头函数但问题是每次组件渲染时都会创建一个新的回调。
参考 前端进阶面试题详细解答
调用 setState 之后发生了什么 在代码中调用 setState 函数之后React 会将传入的参数与之前的状态进行合并然后触发所谓的调和过程Reconciliation。经过调和过程React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面。在 React 得到元素树之后React 会计算出新的树和老的树之间的差异然后根据差异对界面进行最小化重新渲染。通过 diff 算法React 能够精确制导哪些位置发生了改变以及应该如何改变这就保证了按需更新而不是全部重新渲染。 在 setState 的时候React 会为当前节点创建一个 updateQueue 的更新列队。然后会触发 reconciliation 过程在这个过程中会使用名为 Fiber 的调度算法开始生成新的 Fiber 树 Fiber 算法的最大特点是可以做到异步可中断的执行。然后 React Scheduler 会根据优先级高低先执行优先级高的节点具体是执行 doWork 方法。在 doWork 方法中React 会执行一遍 updateQueue 中的方法以获得新的节点。然后对比新旧节点为老节点打上 更新、插入、替换 等 Tag。当前节点 doWork 完成后会执行 performUnitOfWork 方法获得新节点然后再重复上面的过程。当所有节点都 doWork 完成后会触发 commitRoot 方法React 进入 commit 阶段。在 commit 阶段中React 会根据前面为各个节点打的 Tag一次性更新整个 dom 元素
react-redux 的实现原理 通过 redux 和 react context 配合使用并借助高阶函数实现了 react-redux react中的Portal是什么
Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。 第一个参数child是任何可渲染的 React 子元素例如一个元素字符串或碎片。 第二个参数container则是一个 DOM 元素。
ReactDOM.createPortal(child, container)说说 React组件开发中关于作用域的常见问题。
在 EMAScript5语法规范中关于作用域的常见问题如下。 1在map等方法的回调函数中要绑定作用域this通过bind方法。 2父组件传递给子组件方法的作用域是父组件实例化对象无法改变。 3组件事件回调函数方法的作用域是组件实例化对象绑定父组件提供的方法就是父组件实例化对象无法改变。 在 EMAScript6语法规范中关于作用域的常见问题如下。 1当使用箭头函数作为map等方法的回调函数时箭头函数的作用域是当前组件的实例化对象即箭头函数的作用域是定义时的作用域无须绑定作用域。 2事件回调函数要绑定组件作用域。 3父组件传递方法要绑定父组件作用域。 总之在 EMAScript6语法规范中组件方法的作用域是可以改变的。
Component, Element, Instance 之间有什么区别和联系
元素 一个元素element是一个普通对象(plain object)描述了对于一个DOM节点或者其他组件component你想让它在屏幕上呈现成什么样子。元素element可以在它的属性props中包含其他元素(译注:用于形成元素树)。创建一个React元素element成本很低。元素element创建之后是不可变的。组件 一个组件component可以通过多种方式声明。可以是带有一个render()方法的类简单点也可以定义为一个函数。这两种情况下它都把属性props作为输入把返回的一棵元素树作为输出。实例 一个实例instance是你在所写的组件类component class中使用关键字this所指向的东西(译注:组件实例)。它用来存储本地状态和响应生命周期事件很有用。
函数式组件(Functional component)根本没有实例instance。类组件(Class component)有实例instance但是永远也不需要直接创建一个组件的实例因为React帮我们做了这些。
为什么要使用 React. Children. map props. children( ))而不是props. children. map ( ( ) )
因为不能保证 props. children将是一个数组。 以下面的代码为例。
Parenth1有课前端网/h1
/Parent在父组件内部如果尝试使用 props.children. map映射子对象则会抛出错误因为props. children是一个对象而不是一个数组。 如果有多个子元素 React会使 props.children成为一个数组如下所示。
Parenth1有课前端网/h1h2前端技术学习平台/h2
/Parent;
//不建议使用如下方式在这个案例中会抛出错误。class Parent extends Component {render() {return div {this.props.children.map((obj) obj)}/div;}
}建议使用如下方式避免在上一个案例中抛出错误。
class Parent extends Component {render() {return div {React.Children.map(this.props.children, (obj) obj)}/div;}
}何为 Children
在JSX表达式中一个开始标签(比如a)和一个关闭标签(比如/a)之间的内容会作为一个特殊的属性props.children被自动传递给包含着它的组件。
这个属性有许多可用的方法包括 React.Children.mapReact.Children.forEach React.Children.count React.Children.onlyReact.Children.toArray。
简述react事件机制
当用户在为onClick添加函数时React并没有将Click时间绑定在DOM上面 而是在document处监听所有支持的事件当事件发生并冒泡至document处时React将事件内容封装交给中间层SyntheticEvent负责所有事件合成 所以当事件触发的时候对使用统一的分发函数dispatchEvent将指定函数执行。React在自己的合成事件中重写了 stopPropagation方法将 isPropagationStopped设置为 true然后在遍历每一级事件的过程中根据此遍历判断是否继续执行。这就是 React自己实现的冒泡机制
React实现的移动应用中如果出现卡顿有哪些可以考虑的优化方案
增加shouldComponentUpdate钩子对新旧props进行比较如果值相同则阻止更新避免不必要的渲染或者使用PureReactComponent替代Component其内部已经封装了shouldComponentUpdate的浅比较逻辑对于列表或其他结构相同的节点为其中的每一项增加唯一key属性以方便React的diff算法中对该节点的复用减少节点的创建和删除操作render函数中减少类似onClick{() {doSomething()}}的写法每次调用render函数时均会创建一个新的函数即使内容没有发生任何变化也会导致节点没必要的重渲染建议将函数保存在组件的成员对象中这样只会创建一次组件的props如果需要经过一系列运算后才能拿到最终结果则可以考虑使用reselect库对结果进行缓存如果props值未发生变化则结果直接从缓存中拿避免高昂的运算代价webpack-bundle-analyzer分析当前页面的依赖包是否存在不合理性如果存在找到优化点并进行优化
React 中 refs 的作用是什么
Refs 是 React 提供给我们的安全访问 DOM元素或者某个组件实例的句柄可以为元素添加ref属性然后在回调函数中接受该元素在 DOM 树中的句柄该值会作为回调函数的第一个参数返回
用户不同权限 可以查看不同的页面 如何实现
Js方式 根据用户权限类型把菜单配置成json, 没有权限的直接不显示react-router 方式 在route 标签上 添加onEnter事件进入路由之前替换到首页
Route path/home component{App} onEnter{(nexState,replace){if(nexState.location.pathname!/){var sid UtilsMoudle.getSidFromUrl(nexState);if(!sid){replace(/)}else{console.log(sid);}}}}自己封装一个privateRouter组件 里面判断是否有权限有的话返回 没有权限的话component 返回一个提示信息的组件。 扩展一下如果是根据用权限来判断是否隐藏组件该怎么做呢 react 可以使用高阶组件在高阶组件里面判断是否有权限然后判断是否返回组件无权限返回null vue 可以使用自定义指令如果没有权限移除组件
// 需要在入口处添加自定义权限指令v-auth显示可操作组件
Vue.directive(auth, {bind: function (el, binding, vnode) {// 用户权限表const rules authsfor (let i 0; i rules.length; i) {const item rules[i]if(!binding.value || (binding.value item.auth)){// 权限允许则显示组件return true}}// 移除组件el.parentNode.removeChild(el)}
})
// 使用
templatedivButton v-authadmin_user_add添加用户/ButtonButton v-authadmin_user_del删除用户/ButtonButton v-authadmin_user_edit编辑用户/Button/div
/templateReact 数据持久化有什么实践吗
封装数据持久化组件
let storage{// 增加set(key, value){localStorage.setItem(key, JSON.stringify(value));},// 获取get(key){return JSON.parse(localStorage.getItem(key));},// 删除remove(key){localStorage.removeItem(key);}
};
export default Storage;
在React项目中通过redux存储全局数据时会有一个问题如果用户刷新了网页那么通过redux存储的全局数据就会被全部清空比如登录信息等。这时就会有全局数据持久化存储的需求。首先想到的就是localStoragelocalStorage是没有时间限制的数据存储可以通过它来实现数据的持久化存储。
但是在已经使用redux来管理和存储全局数据的基础上再去使用localStorage来读写数据这样不仅是工作量巨大还容易出错。那么有没有结合redux来达到持久数据存储功能的框架呢当然它就是redux-persist。redux-persist会将redux的store中的数据缓存到浏览器的localStorage中。其使用步骤如下
1首先要安装redux-persist
npm i redux-persist
2对于reducer和action的处理不变只需修改store的生成代码修改如下
import {createStore} from redux
import reducers from ../reducers/index
import {persistStore, persistReducer} from redux-persist;
import storage from redux-persist/lib/storage;
import autoMergeLevel2 from redux-persist/lib/stateReconciler/autoMergeLevel2;
const persistConfig {key: root,storage: storage,stateReconciler: autoMergeLevel2 // 查看 Merge Process 部分的具体情况
};
const myPersistReducer persistReducer(persistConfig, reducers)
const store createStore(myPersistReducer)
export const persistor persistStore(store)
export default store
3在index.js中将PersistGate标签作为网页内容的父标签
import React from react;
import ReactDOM from react-dom;
import {Provider} from react-redux
import store from ./redux/store/store
import {persistor} from ./redux/store/store
import {PersistGate} from redux-persist/lib/integration/react;
ReactDOM.render(Provider store{store}PersistGate loading{null} persistor{persistor}{/*网页内容*/} /PersistGate/Provider, document.getElementById(root));
这就完成了通过redux-persist实现React持久化本地数据存储的简单应用。
在生命周期中的哪一步你应该发起 AJAX 请求 我们应当将AJAX 请求放到 componentDidMount 函数中执行主要原因有下 React 下一代调和算法 Fiber 会通过开始或停止渲染的方式优化应用性能其会影响到 componentWillMount 的触发次数。对于 componentWillMount 这个生命周期函数的调用次数会变得不确定React 可能会多次频繁调用 componentWillMount。如果我们将 AJAX 请求放到 componentWillMount 函数中那么显而易见其会被触发多次自然也就不是好的选择。如果我们将AJAX 请求放置在生命周期的其他函数中我们并不能保证请求仅在组件挂载完毕后才会要求响应。如果我们的数据请求在组件挂载之前就完成并且调用了setState函数将数据添加到组件状态中对于未挂载的组件则会报错。而在 componentDidMount 函数中进行 AJAX 请求则能有效避免这个问题
react有什么优点 提高应用性能 可以方便的在客户端和服务端使用 使用jsx模板进行数据渲染可读性好