调度动作创建者使用 componentWillMount 被调用两次
dispacthing actions creator gets called twice using componentWillMount
我使用 componentWillMount 方法调用 action creator, 然后它被调用了两次。查看下面的结果截图。
这是我的动作创作者 :
export function fetchAdmin(){
return (dispatch)=>{
axios.get(`${Config.API_URL}/admin`,{
headers: { authorization: localStorage.getItem('token')}
})
.then(response => {
return dispatch({
type: FETCH_DATA,
payload: response.data
});
}
)
.catch(response => {
console.log(response);
});
}
}
这是我的 reducer :
import { FETCH_DATA } from '../actions/types';
export function admin(state= {}, action){
switch(action.type){
case FETCH_DATA:
return {...state, lists: action.payload };
default:
return { state, lists: 'YEY!'}
}
}
这是我的容器,也是我使用 componentWillMount 调用我的 action creator 的方式。
import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import * as actions from 'actions/admin_action';
class Admin extends Component{
componentWillMount(){
this.props.fetchAdmin()
}
renderData(){
var lists = this.props.lists;
console.log(lists);
}
render(){
return(
<div>
{this.renderData()}
</div>
)
}
const mapStateToProps = (state) => {
return { lists: state.admin.lists };
}
export default connect(mapStateToProps, actions)(Admin);
根据屏幕截图,我假设 render() 被调用了两次。第一次调用转到默认动作创建者,因此结果是 "YEY!",第二次是有效的。
谁能给我解释一下为什么 componentWillMount 会这样执行,实际上在第一个渲染中我只想我的数组不 "YEY!" 如何解决这个问题?谢谢。
这里没有问题!当你的组件第一次渲染时,它在逻辑 componentWillMount
完成之前到达渲染,所以:
第一次渲染: 你的组件渲染时全局状态中的 lists
是默认等于 YEY!
.
第二次渲染:当数据获取成功后,reducer在全局状态lists
中更改为获取的数据,之后你的组件检测由于 mapStateToProps
从全局状态获得 lists
的变化。
不用说 React 组件是在 propsChange 上重新渲染的,这就是为什么有一个方法 componentWillReceiveProps
这样你就可以在每次 props 改变时添加一些逻辑(如果你需要的话)。
此行为允许您处理等待数据被提取的过程:
- 添加加载微调器。
- 呈现您的布局。
- 渲染页面中的其他组件。
Javascript 是异步的。您正在执行的 HTTP 请求是异步的。这意味着 Javascript 在 HTTP 请求仍未决时继续执行。
所以 React 已经在状态仍然是 'Yey' 时呈现。这就是它应该的样子,也是 Redux 的美妙之处,动作是即发即忘,它们不会阻塞。如果 React 等待 HTTP 请求完成,用户体验会很糟糕!
如果您不希望它呈现 'Yey'。您应该在请求仍处于待处理状态时显示加载程序或其他内容。
我使用 componentWillMount 方法调用 action creator, 然后它被调用了两次。查看下面的结果截图。
这是我的动作创作者 :
export function fetchAdmin(){
return (dispatch)=>{
axios.get(`${Config.API_URL}/admin`,{
headers: { authorization: localStorage.getItem('token')}
})
.then(response => {
return dispatch({
type: FETCH_DATA,
payload: response.data
});
}
)
.catch(response => {
console.log(response);
});
}
}
这是我的 reducer :
import { FETCH_DATA } from '../actions/types';
export function admin(state= {}, action){
switch(action.type){
case FETCH_DATA:
return {...state, lists: action.payload };
default:
return { state, lists: 'YEY!'}
}
}
这是我的容器,也是我使用 componentWillMount 调用我的 action creator 的方式。
import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import * as actions from 'actions/admin_action';
class Admin extends Component{
componentWillMount(){
this.props.fetchAdmin()
}
renderData(){
var lists = this.props.lists;
console.log(lists);
}
render(){
return(
<div>
{this.renderData()}
</div>
)
}
const mapStateToProps = (state) => {
return { lists: state.admin.lists };
}
export default connect(mapStateToProps, actions)(Admin);
根据屏幕截图,我假设 render() 被调用了两次。第一次调用转到默认动作创建者,因此结果是 "YEY!",第二次是有效的。
谁能给我解释一下为什么 componentWillMount 会这样执行,实际上在第一个渲染中我只想我的数组不 "YEY!" 如何解决这个问题?谢谢。
这里没有问题!当你的组件第一次渲染时,它在逻辑 componentWillMount
完成之前到达渲染,所以:
第一次渲染: 你的组件渲染时全局状态中的 lists
是默认等于 YEY!
.
第二次渲染:当数据获取成功后,reducer在全局状态lists
中更改为获取的数据,之后你的组件检测由于 mapStateToProps
从全局状态获得 lists
的变化。
不用说 React 组件是在 propsChange 上重新渲染的,这就是为什么有一个方法 componentWillReceiveProps
这样你就可以在每次 props 改变时添加一些逻辑(如果你需要的话)。
此行为允许您处理等待数据被提取的过程:
- 添加加载微调器。
- 呈现您的布局。
- 渲染页面中的其他组件。
Javascript 是异步的。您正在执行的 HTTP 请求是异步的。这意味着 Javascript 在 HTTP 请求仍未决时继续执行。
所以 React 已经在状态仍然是 'Yey' 时呈现。这就是它应该的样子,也是 Redux 的美妙之处,动作是即发即忘,它们不会阻塞。如果 React 等待 HTTP 请求完成,用户体验会很糟糕!
如果您不希望它呈现 'Yey'。您应该在请求仍处于待处理状态时显示加载程序或其他内容。