网站辅助导航,怎样做淘宝联盟网站,sem分析是什么,南昌市经济技术开发区属于哪个区说说你用react有什么坑点#xff1f;
1. JSX做表达式判断时候#xff0c;需要强转为boolean类型 如果不使用 !!b 进行强转数据类型#xff0c;会在页面里面输出 0。 render() {const b 0;return div{!!b div这是一段文本/div}/div…说说你用react有什么坑点
1. JSX做表达式判断时候需要强转为boolean类型 如果不使用 !!b 进行强转数据类型会在页面里面输出 0。 render() {const b 0;return div{!!b div这是一段文本/div}/div
}2. 尽量不要在 componentWillReviceProps 里使用 setState如果一定要使用那么需要判断结束条件不然会出现无限重渲染导致页面崩溃
3. 给组件添加ref时候尽量不要使用匿名函数因为当组件更新的时候匿名函数会被当做新的prop处理让ref属性接受到新函数的时候react内部会先清空ref也就是会以null为回调参数先执行一次ref这个props然后在以该组件的实例执行一次ref所以用匿名函数做ref的时候有的时候去ref赋值后的属性会取到null
4. 遍历子节点的时候不要用 index 作为组件的 key 进行传入
React中的props为什么是只读的
this.props是组件之间沟通的一个接口原则上来讲它只能从父组件流向子组件。React具有浓重的函数式编程的思想。
提到函数式编程就要提一个概念纯函数。它有几个特点
给定相同的输入总是返回相同的输出。过程没有副作用。不依赖外部状态。
this.props就是汲取了纯函数的思想。props的不可以变性就保证的相同的输入页面显示的内容是一样的并且不会产生副作用
高阶组件存在的问题
静态方法丢失(必须将静态方法做拷贝)refs 属性不能透传(如果你向一个由高阶组件创建的组件的元素添加ref引用那么ref指向的是最外层容器组件实例的而不是被包裹的WrappedComponent组件。)反向继承不能保证完整的子组件树被解析 React 组件有两种形式分别是 class 类型和 function 类型无状态组件。
我们知道反向继承的渲染劫持可以控制 WrappedComponent 的渲染过程也就是说这个过程中我们可以对 elements tree、 state、 props 或 render() 的结果做各种操作。
但是如果渲染 elements tree 中包含了 function 类型的组件的话这时候就不能操作组件的子组件了。
对有状态组件和无状态组件的理解及使用场景
1有状态组件
特点
是类组件有继承可以使用this可以使用react的生命周期使用较多容易频繁触发生命周期钩子函数影响性能内部使用 state维护自身状态的变化有状态组件根据外部组件传入的 props 和自身的 state进行渲染。
使用场景
需要使用到状态的。需要使用状态操作组件的无状态组件的也可以实现新版本react hooks也可实现
总结 类组件可以维护自身的状态变量即组件的 state 类组件还有不同的生命周期方法可以让开发者能够在组件的不同阶段挂载、更新、卸载对组件做更多的控制。类组件则既可以充当无状态组件也可以充当有状态组件。当一个类组件不需要管理自身状态时也可称为无状态组件。
2无状态组件 特点
不依赖自身的状态state可以是类组件或者函数组件。可以完全避免使用 this 关键字。由于使用的是箭头函数事件无需绑定有更高的性能。当不需要使用生命周期钩子时应该首先使用无状态函数组件组件内部不维护 state 只根据外部组件传入的 props 进行渲染的组件当 props 改变时组件重新渲染。
使用场景
组件不需要管理 state纯展示
优点
简化代码、专注于 render组件不需要被实例化无生命周期提升性能。 输出渲染只取决于输入属性无副作用视图和数据的解耦分离
缺点
无法使用 ref无生命周期方法无法控制组件的重渲染因为无法使用shouldComponentUpdate 方法当组件接受到新的属性时则会重渲染
总结 组件内部状态且与外部无关的组件可以考虑用状态组件这样状态树就不会过于复杂易于理解和管理。当一个组件不需要管理自身状态时也就是无状态组件应该优先设计为函数组件。比如自定义的 Button/、 Input / 等组件。
什么是受控组件和非受控组件
受状态控制的组件必须要有onChange方法否则不能使用 受控组件可以赋予默认值官方推荐使用 受控组件 实现双向数据绑定
class Input extends Component{constructor(){super();this.state {val:100}}handleChange (e) { //e是事件源let val e.target.value;this.setState({val});};render(){return (divinput typetext value{this.state.val} onChange{this.handleChange}/{this.state.val}/div)}
}
非受控也就意味着我可以不需要设置它的state属性而通过ref来操作真实的DOM
class Sum extends Component{constructor(){super();this.state {result:}}//通过ref设置的属性 可以通过this.refs获取到对应的dom元素handleChange () {let result this.refs.a.value this.b.value;this.setState({result});};render(){return (div onChange{this.handleChange}input typenumber refa/{/*x代表的真实的dom,把元素挂载在了当前实例上*/}input typenumber ref{(x){this.b x;}}/{this.state.result}/div)}
}React 16中新生命周期有哪些
关于 React16 开始应用的新生命周期 可以看出React16 自上而下地对生命周期做了另一种维度的解读
Render 阶段用于计算一些必要的状态信息。这个阶段可能会被 React 暂停这一点和 React16 引入的 Fiber 架构我们后面会重点讲解是有关的Pre-commit阶段所谓“commit”这里指的是“更新真正的 DOM 节点”这个动作。所谓 Pre-commit就是说我在这个阶段其实还并没有去更新真实的 DOM不过 DOM 信息已经是可以读取的了Commit 阶段在这一步React 会完成真实 DOM 的更新工作。Commit 阶段我们可以拿到真实 DOM包括 refs。
与此同时新的生命周期在流程方面仍然遵循“挂载”、“更新”、“卸载”这三个广义的划分方式。它们分别对应到
挂载过程 constructorgetDerivedStateFromPropsrendercomponentDidMount 更新过程 getDerivedStateFromPropsshouldComponentUpdaterendergetSnapshotBeforeUpdatecomponentDidUpdate 卸载过程 componentWillUnmount
参考 前端进阶面试题详细解答
React中什么是受控组件和非控组件
1受控组件 在使用表单来收集用户输入时例如inputselecttextearea等元素都要绑定一个change事件当表单的状态发生变化就会触发onChange事件更新组件的state。这种组件在React中被称为受控组件在受控组件中组件渲染出的状态与它的value或checked属性相对应react通过这种方式消除了组件的局部状态使整个状态可控。react官方推荐使用受控表单组件。
受控组件更新state的流程
可以通过初始state中设置表单的默认值每当表单的值发生变化时调用onChange事件处理器事件处理器通过事件对象e拿到改变后的状态并更新组件的state一旦通过setState方法更新state就会触发视图的重新渲染完成表单组件的更新
受控组件缺陷 表单元素的值都是由React组件进行管理当有多个输入框或者多个这种组件时如果想同时获取到全部的值就必须每个都要编写事件处理函数这会让代码看着很臃肿所以为了解决这种情况出现了非受控组件。
2非受控组件 如果一个表单组件没有value props单选和复选按钮对应的是checked props时就可以称为非受控组件。在非受控组件中可以使用一个ref来从DOM获得表单值。而不是为每个状态更新编写一个事件处理程序。
React官方的解释 要编写一个非受控组件而不是为每个状态更新都编写数据处理函数你可以使用 ref来从 DOM 节点中获取表单数据。 因为非受控组件将真实数据储存在 DOM 节点中所以在使用非受控组件时有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性并且希望快速编写代码使用非受控组件往往可以减少你的代码量。否则你应该使用受控组件。 例如下面的代码在非受控组件中接收单个属性
class NameForm extends React.Component {constructor(props) {super(props);this.handleSubmit this.handleSubmit.bind(this);}handleSubmit(event) {alert(A name was submitted: this.input.value);event.preventDefault();}render() {return (form onSubmit{this.handleSubmit}labelName: input typetext ref{(input) this.input input} / /labelinput typesubmit valueSubmit //form);}
}
总结 页面中所有输入类的DOM如果是现用现取的称为非受控组件而通过setState将输入的值维护到了state中需要时再从state中取出这里的数据就受到了state的控制称为受控组件。
Redux 中异步的请求怎么处理
可以在 componentDidmount 中直接进⾏请求⽆须借助redux。但是在⼀定规模的项⽬中,上述⽅法很难进⾏异步流的管理,通常情况下我们会借助redux的异步中间件进⾏异步处理。redux异步流中间件其实有很多当下主流的异步中间件有两种redux-thunk、redux-saga。
1使用react-thunk中间件
redux-thunk优点:
体积⼩: redux-thunk的实现⽅式很简单,只有不到20⾏代码使⽤简单: redux-thunk没有引⼊像redux-saga或者redux-observable额外的范式,上⼿简单
redux-thunk缺陷:
样板代码过多: 与redux本身⼀样,通常⼀个请求需要⼤量的代码,⽽且很多都是重复性质的耦合严重: 异步操作与redux的action偶合在⼀起,不⽅便管理功能孱弱: 有⼀些实际开发中常⽤的功能需要⾃⼰进⾏封装
使用步骤
配置中间件在store的创建中配置
import {createStore, applyMiddleware, compose} from redux;
import reducer from ./reducer;
import thunk from redux-thunk// 设置调试工具
const composeEnhancers window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
// 设置中间件
const enhancer composeEnhancers(applyMiddleware(thunk)
);const store createStore(reducer, enhancer);export default store;
添加一个返回函数的actionCreator将异步请求逻辑放在里面
/** 发送get请求并生成相应action更新store的函数 param url {string} 请求地址 param func {function} 真正需要生成的action对应的actionCreator return {function} */
// dispatch为自动接收的store.dispatch函数
export const getHttpAction (url, func) (dispatch) {axios.get(url).then(function(res){const action func(res.data)dispatch(action)})
}
生成action并发送action
componentDidMount(){var action getHttpAction(/getData, getInitTodoItemAction)// 发送函数类型的action时该action的函数体会自动执行store.dispatch(action)
}
2使用redux-saga中间件
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,学习成本远超redux-thunk,最重要的是你的额外学习成本是只服务于这个库的,与redux-observable不同,redux-observable虽然也有额外学习成本但是背后是rxjs和⼀整套思想体积庞⼤: 体积略⼤,代码近2000⾏min版25KB左右功能过剩: 实际上并发控制等功能很难⽤到,但是我们依然需要引⼊这些代码ts⽀持不友好: yield⽆法返回TS类型
redux-saga可以捕获action然后执行一个函数那么可以把异步代码放在这个函数中使用步骤如下
配置中间件
import {createStore, applyMiddleware, compose} from redux;
import reducer from ./reducer;
import createSagaMiddleware from redux-saga
import TodoListSaga from ./sagasconst composeEnhancers window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const sagaMiddleware createSagaMiddleware()const enhancer composeEnhancers(applyMiddleware(sagaMiddleware)
);const store createStore(reducer, enhancer);
sagaMiddleware.run(TodoListSaga)export default store;
将异步请求放在sagas.js中
import {takeEvery, put} from redux-saga/effects
import {initTodoList} from ./actionCreator
import {GET_INIT_ITEM} from ./actionTypes
import axios from axiosfunction* func(){try{// 可以获取异步返回数据const res yield axios.get(/getData)const action initTodoList(res.data)// 将action发送到reduceryield put(action)}catch(e){console.log(网络请求失败)}
}function* mySaga(){// 自动捕获GET_INIT_ITEM类型的action并执行funcyield takeEvery(GET_INIT_ITEM, func)
}export default mySaga
发送action
componentDidMount(){const action getInitTodoItemAction()store.dispatch(action)
}
对 React-Intl 的理解它的工作原理
React-intl是雅虎的语言国际化开源项目FormatJS的一部分通过其提供的组件和API可以与ReactJS绑定。
React-intl提供了两种使用方法一种是引用React组件另一种是直接调取API官方更加推荐在React项目中使用前者只有在无法使用React组件的地方才应该调用框架提供的API。它提供了一系列的React组件包括数字格式化、字符串格式化、日期格式化等。
在React-intl中可以配置不同的语言包他的工作原理就是根据需要在语言包之间进行切换。
对 React context 的理解
在React中数据传递一般使用props传递数据维持单向数据流这样可以让组件之间的关系变得简单且可预测但是单项数据流在某些场景中并不适用。单纯一对的父子组件传递并无问题但要是组件之间层层依赖深入props就需要层层传递显然这样做太繁琐了。
Context 提供了一种在组件之间共享此类值的方式而不必显式地通过组件树的逐层传递 props。
可以把context当做是特定一个组件树内共享的store用来做数据传递。简单说就是当你不想在组件树中通过逐层传递props或者state的方式来传递数据时可以使用Context来实现跨层级的组件数据传递。
JS的代码块在执行期间会创建一个相应的作用域链这个作用域链记录着运行时JS代码块执行期间所能访问的活动对象包括变量和函数JS程序通过作用域链访问到代码块内部或者外部的变量和函数。
假如以JS的作用域链作为类比React组件提供的Context对象其实就好比一个提供给子组件访问的作用域而 Context对象的属性可以看成作用域上的活动对象。由于组件 的 Context 由其父节点链上所有组件通 过 getChildContext返回的Context对象组合而成所以组件通过Context是可以访问到其父组件链上所有节点组件提供的Context的属性。
为什么React并不推荐优先考虑使用Context
Context目前还处于实验阶段可能会在后面的发行版本中有很大的变化事实上这种情况已经发生了所以为了避免给今后升级带来大的影响和麻烦不建议在app中使用context。尽管不建议在app中使用context但是独有组件而言由于影响范围小于app如果可以做到高内聚不破坏组件树之间的依赖关系可以考虑使用context对于组件之间的数据通信或者状态管理有效使用props或者state解决然后再考虑使用第三方的成熟库进行解决以上的方法都不是最佳的方案的时候在考虑context。context的更新需要通过setState()触发但是这并不是很可靠的Context支持跨组件的访问但是如果中间的子组件通过一些方法不影响更新比如 shouldComponentUpdate() 返回false 那么不能保证Context的更新一定可以使用Context的子组件因此Context的可靠性需要关注
React中refs的作用是什么有哪些应用场景
Refs 提供了一种方式用于访问在 render 方法中创建的 React 元素或 DOM 节点。Refs 应该谨慎使用如下场景使用 Refs 比较适合
处理焦点、文本选择或者媒体的控制触发必要的动画集成第三方 DOM 库
Refs 是使用 React.createRef() 方法创建的他通过 ref 属性附加到 React 元素上。要在整个组件中使用 Refs需要将 ref 在构造函数中分配给其实例属性
class MyComponent extends React.Component {constructor(props) {super(props)this.myRef React.createRef()}render() {return div ref{this.myRef} /}
}
由于函数组件没有实例因此不能在函数组件上直接使用 ref
function MyFunctionalComponent() {return input /;
}
class Parent extends React.Component {constructor(props) {super(props);this.textInput React.createRef();}render() {// 这将不会工作return (MyFunctionalComponent ref{this.textInput} /);}
}
但可以通过闭合的帮助在函数组件内部进行使用 Refs
function CustomTextInput(props) {// 这里必须声明 textInput这样 ref 回调才可以引用它let textInput null;function handleClick() {textInput.focus();}return (divinputtypetextref{(input) { textInput input; }} / inputtypebuttonvalueFocus the text inputonClick{handleClick}//div);
}
注意
不应该过度的使用 Refsref 的返回值取决于节点的类型 当 ref 属性被用于一个普通的 HTML 元素时React.createRef() 将接收底层 DOM 元素作为他的 current 属性以创建 ref。当 ref 属性被用于一个自定义的类组件时ref 对象将接收该组件已挂载的实例作为他的 current。 当在父组件中需要访问子组件中的 ref 时可使用传递 Refs 或回调 Refs。
React声明组件有哪几种方法有什么不同
React 声明组件的三种方式
函数式定义的无状态组件ES5原生方式React.createClass定义的组件ES6形式的extends React.Component定义的组件
1无状态函数式组件 它是为了创建纯展示组件这种组件只负责根据传入的props来展示不涉及到state状态的操作 组件不会被实例化整体渲染性能得到提升不能访问this对象不能访问生命周期的方法
2ES5 原生方式 React.createClass // RFC React.createClass会自绑定函数方法导致不必要的性能开销增加代码过时的可能性。
3E6继承形式 React.Component // RCC 目前极为推荐的创建有状态组件的方式最终会取代React.createClass形式相对于 React.createClass可以更好实现代码复用。
无状态组件相对于于后者的区别 与无状态组件相比React.createClass和React.Component都是创建有状态的组件这些组件是要被实例化的并且可以访问组件的生命周期方法。
React.createClass与React.Component区别
① 函数this自绑定
React.createClass创建的组件其每一个成员函数的this都有React自动绑定函数中的this会被正确设置。React.Component创建的组件其成员函数不会自动绑定this需要开发者手动绑定否则this不能获取当前组件实例对象。
② 组件属性类型propTypes及其默认props属性defaultProps配置不同
React.createClass在创建组件时有关组件props的属性类型及组件默认的属性会作为组件实例的属性来配置其中defaultProps是使用getDefaultProps的方法来获取默认组件属性的React.Component在创建组件时配置这两个对应信息时他们是作为组件类的属性不是组件实例的属性也就是所谓的类的静态属性来配置的。
③ 组件初始状态state的配置不同
React.createClass创建的组件其状态state是通过getInitialState方法来配置组件相关的状态React.Component创建的组件其状态state是在constructor中像初始化组件属性一样声明的。
React中发起网络请求应该在哪个生命周期中进行为什么
对于异步请求最好放在componentDidMount中去操作对于同步的状态改变可以放在componentWillMount中一般用的比较少。
如果认为在componentWillMount里发起请求能提早获得结果这种想法其实是错误的通常componentWillMount比componentDidMount早不了多少微秒网络上任何一点延迟这一点差异都可忽略不计。
react的生命周期 constructor() - componentWillMount() - render() - componentDidMount()
上面这些方法的调用是有次序的由上而下依次调用。
constructor被调用是在组件准备要挂载的最开始此时组件尚未挂载到网页上。componentWillMount方法的调用在constructor之后在render之前在这方法里的代码调用setState方法不会触发重新render所以它一般不会用来作加载数据之用。componentDidMount方法中的代码是在组件已经完全挂载到网页上才会调用被执行所以可以保证数据的加载。此外在这方法中调用setState方法会触发重新渲染。所以官方设计这个方法就是用来加载外部数据用的或处理其他的副作用代码。与组件上的数据无关的加载也可以在constructor里做但constructor是做组件state初绐化工作并不是做加载数据这工作的constructor里也不能setState还有加载的时间太长或者出错页面就无法加载出来。所以有副作用的代码都会集中在componentDidMount方法里。
总结
跟服务器端渲染同构有关系如果在componentWillMount里面获取数据fetch data会执行两次一次在服务器端一次在客户端。在componentDidMount中可以解决这个问题componentWillMount同样也会render两次。在componentWillMount中fetch data数据一定在render后才能到达如果忘记了设置初始状态用户体验不好。react16.0以后componentWillMount可能会被执行多次。
在React中组件的props改变时更新组件的有哪些方法
在一个组件传入的props更新时重新渲染该组件常用的方法是在componentWillReceiveProps中将新的props更新到组件的state中这种state被成为派生状态Derived State从而实现重新渲染。React 16.3中还引入了一个新的钩子函数getDerivedStateFromProps来专门实现这一需求。
1componentWillReceiveProps已废弃
在react的componentWillReceiveProps(nextProps)生命周期中可以在子组件的render函数执行前通过this.props获取旧的属性通过nextProps获取新的props对比两次props是否相同从而更新子组件自己的state。
这样的好处是可以将数据请求放在这里进行执行需要传的参数则从componentWillReceiveProps(nextProps)中获取。而不必将所有的请求都放在父组件中。于是该请求只会在该组件渲染时才会发出从而减轻请求负担。
2getDerivedStateFromProps16.3引入
这个生命周期函数是为了替代componentWillReceiveProps存在的所以在需要使用componentWillReceiveProps时就可以考虑使用getDerivedStateFromProps来进行替代。
两者的参数是不相同的而getDerivedStateFromProps是一个静态函数也就是这个函数不能通过this访问到class的属性也并不推荐直接访问属性。而是应该通过参数提供的nextProps以及prevState来进行判断根据新传入的props来映射到state。
需要注意的是如果props传入的内容不需要影响到你的state那么就需要返回一个null这个返回值是必须的所以尽量将其写到函数的末尾
static getDerivedStateFromProps(nextProps, prevState) {const {type} nextProps;// 当传入的type发生变化的时候更新stateif (type ! prevState.type) {return {type,};}// 否则对于state不进行任何操作return null;
}
解释 React 中 render() 的目的。
每个React组件强制要求必须有一个 render()。它返回一个 React 元素是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素则必须将它们组合在一个封闭标记内例如 form、group、div 等。此函数必须保持纯净即必须每次调用时都返回相同的结果。
哪些方法会触发 React 重新渲染重新渲染 render 会做些什么
1哪些方法会触发 react 重新渲染?
setState方法被调用
setState 是 React 中最常用的命令通常情况下执行 setState 会触发 render。但是这里有个点值得关注执行 setState 的时候不一定会重新渲染。当 setState 传入 null 时并不会触发 render。
class App extends React.Component {state {a: 1};render() {console.log(render);return (React.Fragementp{this.state.a}/pbuttononClick{() { this.setState({ a: 1 }); // 这里并没有改变 a 的值 }} Click me /buttonbutton onClick{() this.setState(null)}setState null/buttonChild //React.Fragement);}
}
父组件重新渲染
只要父组件重新渲染了即使传入子组件的 props 未发生变化那么子组件也会重新渲染进而触发 render
2重新渲染 render 会做些什么?
会对新旧 VNode 进行对比也就是我们所说的Diff算法。对新旧两棵树进行一个深度优先遍历这样每一个节点都会一个标记在到深度遍历的时候每遍历到一和个节点就把该节点和新的节点树进行对比如果有差异就放到一个对象里面遍历差异对象根据差异的类型根据对应对规则更新VNode
React 的处理 render 的基本思维模式是每次一有变动就会去重新渲染整个应用。在 Virtual DOM 没有出现之前最简单的方法就是直接调用 innerHTML。Virtual DOM厉害的地方并不是说它比直接操作 DOM 快而是说不管数据怎么变都会尽量以最小的代价去更新 DOM。React 将 render 函数返回的虚拟 DOM 树与老的进行比较从而确定 DOM 要不要更新、怎么更新。当 DOM 树很大时遍历两棵树进行各种比对还是相当耗性能的特别是在顶层 setState 一个微小的修改默认会去遍历整棵树。尽管 React 使用高度优化的 Diff 算法但是这个过程仍然会损耗性能.
React.Children.map和js的map有什么区别
JavaScript中的map不会对为null或者undefined的数据进行处理而React.Children.map中的map可以处理React.Children为null或者undefined的情况。
useEffect和useLayoutEffect的区别
useEffect 基本上90%的情况下,都应该用这个,这个是在render结束后,你的callback函数执行,但是不会block browser painting,算是某种异步的方式吧,但是class的componentDidMount 和componentDidUpdate是同步的,在render结束后就运行,useEffect在大部分场景下都比class的方式性能更好. useLayoutEffect 这个是用在处理DOM的时候,当你的useEffect里面的操作需要处理DOM,并且会改变页面的样式,就需要用这个,否则可能会出现出现闪屏问题, useLayoutEffect里面的callback函数会在**DOM更新完成后立即执行,但是会在浏览器进行任何绘制之前运行完成,**阻塞了浏览器的绘制.
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{};}}