【发布时间】:2017-04-11 02:46:38
【问题描述】:
我有一个 React 组件,它显示 NBA 球队的列表和有关他们的信息。
我创建了一个位于左侧并提供团队列表的 TeamsList 组件。然后我有一个 TeamInfo 组件,它提供有关“选定”团队的信息。
在 MyMainComponent 的父入口点,我读取了团队列表并将其放入我的 redux 存储中。
这是我想要弄清楚的:我想自动进行 API 调用以获取有关列表中第一个团队的信息。我应该在 MyMainComponent 中为此使用哪个生命周期事件,例如ComponentWillMount、ComponentDidMount 甚至是构造函数?
class MyMainComponent extends Component {
render() {
const teams = this.props.teamsList;
const team = this.props.team;
return(
<div>
<div class="leftColumn">
<TeamsList data={teams} />
</div>
<div class="rightColumn">
<TeamInfo data={team} />
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
teamsList: state.teamsList,
team: state.team
};
}
export default connect(mapStateToProps)(MyMainComponent)
更新: 我现在正在使用下面的代码在我的操作中处理这个问题,但由于某种原因,我无法拯救我所在州的第一支球队。我将团队的初始状态设置为一个空对象。我通过我的操作/reducer 来更新状态,但由于某种原因,即使teamList 中有正确的数据,我仍然为团队获取一个空对象。为了阐明我在做什么,在入口点,我只需调用 getTeamsList() 函数,它会自动调用 getTeam() 函数。我知道这工作正常。我也知道我正在使用 reducer 来更新 teamsList 和 team 的状态。
export const setTeamsList = (teams) => {
return {
type: types.SET_TEAMS_LIST,
teams
};
}
export const setTeamInfo = (team) => {
return {
type: types.SET_TEAM_INFO,
team
};
}
export const setIsLoading = (value) => {
return{
type: types.SET_IS_LOADING,
value
};
}
export const getTeamsList = () => {
return (dispatch) => {
fetch('/api/teams', fetchOptionsGet())
.then(parseJSON)
.then(teams => {
dispatch(setTeamsList(teams))
dispatch(setIsLoading(true))
if(teams !== null && teams.length > 0)
return dispatch(getTeam(teams[0].teamId))
})
.then(() => dispatch(setIsLoading(false)))
};
}
export const getTeam = (id) => {
return (dispatch) => {
fetch('/api/team/' + id, fetchOptionsGet())
.then(parseJSON)
.then(team => {
dispatch(setTeamInfo(team))
})
};
}
这是我的减速器:
import 'babel-polyfill';
import * as types from '../actions/actionTypes';
const initialState = {
teamsList: [],
team: {}
};
export default (state = initialState, action) => {
switch (action.type) {
case types.SET_TEAMS_LIST :
return Object.assign({}, state, {
teamsList: action.teams
})
case types.SET_TEAM_INFO :
return Object.assign({}, state, {
team: action.team
})
case types.SET_IS_LOADING:
return Object.assign({}, state, {
value: action.value
})
default: return state
}
}
更新 2: 看起来正在执行的操作顺序不是我需要的方式。我以为我可以通过将它们包装在另一个函数中来控制序列,然后同步运行,但这也不起作用。
如果您查看我为使事情顺利进行而调用的 initTeams 函数,您会发现 setIsLoading 步骤首先执行——实际上是背靠背。我看到代码首先点击减速器将 isLoading 设置为 true,然后立即将其设置为 false。然后它执行 getTeamsList()。从那里它实际上进入了 TeamInfo 组件的渲染功能。完成这一切后,它会调用 getTeam() 函数将第一个团队加载到商店中。
更新 3: 差不多了,但仍需要澄清。我现在更好地理解了thunks。仍然让我感到困惑的一件事是:我更新了我的 getTeamsList() 函数,我希望它按以下顺序执行操作:
- 进行 API 调用以获取团队列表
- 在商店中设置团队列表
- 在存储中将 isLoading 设置为 True
- 如果我有团队,请调用 getTeam() 操作以获取团队信息
- 在商店中设置团队信息
- 将 isLoading 设置为 False
相反,它会在第 3 步之后执行第 6 步,然后是第 4 步和第 5 步。
最终,我得到了我想要的结果,但我想了解如何让它以正确的顺序执行我想要执行的步骤。
【问题讨论】:
-
你有 SSR(服务器端渲染)吗?