1.组件挂载阶段通信
React组件的正常运转本质上是组件不同生命周期方法的有序执行,因此组件与服务器的通信也必定依赖组件的生命周期方法。我们先
来看一下组件在挂载阶段如何与服务器通信。
定义一个UserListContainer组件,需要从服务器获取用户列表:
class UserListContainer extends React.Component {
componentWillMount(){//组件挂载前
}
componentDidMount() { //组件挂载中
var that = this;
fetch('/path/to/user-api').then(function(response) {
response.json().then(function(data) {
that.setState({users: data})
});
});
}
}
componentWillMount会在组件被挂载前调用,因此从时间上来讲, 在componentWillMount中执行服务器通信要早于在componentDidMount中执行,执行得越早意味着服务器数据越能更快地返回组件。这也是很多人青睐在componentWillMount中执行服务器通信的重要原因。但实际上,componentWillMount与componentDidMount执行的时间差微乎其微,完全可以忽略不计。
componentDidMount是执行组件与服务器通信的最佳地方,原因主 要有两个:
(1)在componentDidMount中执行服务器通信可以保证获取到数据 时,组件已经处于挂载状态,这时即使要直接操作DOM也是安全的,
而componentWillMount无法保证这一点。
(2)当组件在服务器端渲染时(本书不涉及服务器渲染内容),componentWillMount会被调用两次,一次是在服务器端,另一次是在浏
览器端,而componentDidMount能保证在任何情况下只会被调用一次,从而不会发送多余的数据请求。有些开发人员会在组件的构造函数中执行服务器通信,一般情况下,这种方式也可以正常工作。但是,构造函数的意义是执行组件的初始化工作,如设置组件的初始状态,并不适合做数据请求这类有“副作用”的工作。因此,不推荐在构造函数中执行服务器通信。
2.组件更新阶段通信
组件在更新阶段常常需要再次与服务器通信,获取服务器上的最新数据。例如,组件需要以props中的某个属性作为与服务器通信时的请
求参数,当这个属性值发生更新时,组件自然需要重新与服务器通信。回想2.3节中对组件生命周期的介绍,不难发现componentWillReceiveProps非常适合做这个工作。假设UserListContainer在获取用户列表时还需要一个参数category,用来根据用户的职业做筛选,category这个参数是从props中获取的,实现代码如下:
class UserListContainer extends React.Component{
componentWillReceiveProps(nextProps) {
if(nextProps.category !== this.props.category) {
fetch('/path/to/user-api?category='+nextProps.category). then(function(response) {
response.json().then(function(data) {
that.setState({users: data})
});
});
}
}
}
这里还有一个地方要注意,在执行fetch请求时,要先对新老props 中的category做比较,只有不一致才说明category有了更新,才需要重新
进行服务器通信。componentWillReceiveProps的执行并不能保证props一定发生了修改。
网友评论