调用setState之后发生了什么?
在代码中调用setState函数之后,
1. React会将传入的参数对象与组件当前的状态合并,然后触发所谓
的调和过程(Reconciliation)。
2. 经过调和过程,React会以相对高效的方式根据新的状态构建React。
3. 元素树并且着手重新渲染整个UI界面。
4. 在React得到元素树之后,React会自动计算出新的树与老树的节点差异,
5. 根据差异对界面进行最小化重渲染。在差异计算算法中,React能够相对精确地知道哪些位置发生了改变
以及该如何改变,这就保证了按需更新,而不是全部重新渲染。
在生命周期中的哪一步你应该发起AJAX请求?为什么?
将AJAX请求放到componentDidMount函数中执行。
原因如下:
1. React 下一代调和算法Fiber会通过开始或停止渲染的方式优化性能,其会影响到componentWillMount
的触发次数。对于componentWillMount这个生命周期函数的条用次数会变得不确定,React可能会多次频繁调用componentWillMount。如果我们将AJAX请求放到componentWillMount函数中,那么显而易见
其会被触发多次,自然也就不是好的选择。
2. *如果我们将AJAX请求放置在生命周期的其他函数中,我们并不能保证请求仅在组件挂载完毕后
才会要求响应。如果我们的数据请求在组件挂载之前就完成,并且调用了setState函数将数据添加到
组件状态中,对于未挂载的组件则会报错。而在componentDidMount函数中进行AjAX请求则能有效避免
这个问题。
简述React组件的生命周期
组件的生命周期可分成三个状态:
1. Mounting:已插入真实DOM
2. Updating:正在被重新渲染
3. Unmounting:已移出真实DOM
生命周期的方法有:
- componentWillMount 在渲染钱调用,在客户端也在服务器
- componentDidMount 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过
this.getDOMNode()来进行访问。如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout,
setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
- componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。
- shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用
forceUpdate时不被调用。可以在你确认不需要更新组件时使用。
- componentWillUpdate 在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
- componentDidUpdate 在组件完成更闹心后立即调用。在初始化时不会被调用。
- componentWillUnmount 在组件从DOM中移除的时候立刻被调用。
React中keys的作用是什么?特点?并举例说明key的用法。
作用: keys是React用于追踪哪些列表中元素被修改,被添加或者被移除的辅助标识。
render() {
return(
<ul>
{ this.state.list.map(({item, key}) => {
return <li key={key}>{item}</li>
})}
</ul>
);
}
在开发过程中,我们需要保证某个元素的key在 其同级元素中具有唯一性。在React Diff算法
中React会借助元素额key值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要
的元素重渲染。此外,React还需要借助Key值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换
函数中Key的重要性。
react native网络图片加载不出来的原因是什么?怎么解决?
在IOS9版本以后,默认的网络请求是https,如果是http请求,需要手动解决。
- 找到info.plist文件,用Xcode打开。
- 找到App Transport Security Settings选项下的子选项Allow Arbitrary Loads
- 将Allow Arbitrary Loads 设置为YES
假设数据源为rows=[“row1”,”row2”,”row3”],请用listView展示rows的每一项
import React, { Component} from 'react';
import {
ListView,
View,
Text
} from 'react';
export default class MyListView from Component {
constructor(props) {
super(props)
var ds = ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.state = {
dataSource: ds.cloneWidthRows(rows)
}
}
_renderRow(item) {
return (
<View>
<Text>{item}</Text>
</View>
);
}
render() {
return (
<View style={{ flex: 1 }}>
<ListView
renderRow={ this._renderRow.bind(this) }
dataSource={ this.state.dataSource }
/>
</View>
);
}
}
假设我有一个组件叫做FirstPage,请用Navigator实现以FirstPage为首页的效果
import React, { Component} from 'react';
import {
Navigator
} from 'react-native';
export default class Nav extends Component {
render() {
initialRoute = {
component: FirstPage,
nextPass: {}
}
return (
<Navigator
initialRoute={ initialRoute }
configureScene={ (route) => Navigator.SceneConfigs.PushFromRight }
renderScene={ (route, navigator) => {
// 要渲染的页面
var component = route.component;
// 渲染组件时,将组件的属性也传递过去
return <Navigator { ...route.nextPass } route={ route } navigator={ navigator } />;
/>
);
}
}
请用TabBarIOS实现一个标签栏,其中标签栏包括两个标签,分别为首页电影。其中首页默认被选中
import React, { Component } from 'react';
import {
TabBarIOS,
View,
Text
} from 'react-native';
class HomeComponent extends Component {
render() {
return (
<View>
<Text>这是首页页面</Text>
</View>
);
}
}
class MovieComponent extends Component {
render() {
return (
<View>
<Text>这是电影页面</Text>
</View>
);
}
}
export default class TitleComponent extends Component {
render() {
return (
<TabBarIOS>
<TabBarIOS.Item
title="首页"
selected={ true }
>
<HomeComponent/>
</TabBarIOS.Item>
<TabBarIOS.Item
title="电影"
>
<MovieComponent/>
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
shouldComponentUpdate的作用是啥以及为何它这么重要?
shouldComponetUpdate允许我们手动地判断是否要进行组件更新,根据组件的应用场景设置函数的合理返回值
能够帮助我们避免不必要的更新。
为什么我们需要使用React提供的Children API 而不是Javascript的map?
props.children并不一定是数组类型,臂如下面这个元素:
<Parent>
<h1>Welcom</h1>
</Parent>
如果我们使用props.children.map函数来遍历时会受到异常提示,因为在这种情况下props.children
是对象(object)而不是数组(array)。React当且仅当超过一个子元素的情况下会将props.children设置为数组,就像
下面这个代码片:
<Parent>
<h1>Welcom</h1>
<h2>Hello World</h2>
</Parent>
这也就是我们优先选择使用React.Children.map函数的原因,其已经将props.children不同类型的情况
考虑在内了。