【发布时间】:2018-12-19 03:43:56
【问题描述】:
我有一个 React 应用程序,它使用 React-Router/React-Router-dom 进行页面导航和 redux 来存储一些全局状态信息(例如 django rest 框架的 jwt 令牌)。该状态还存储有关当前查看的页面的信息,例如序列化的 django 模型。
但是当路由发生变化时,将 django 模型加载到 redux 存储中的最佳方法是什么?我在思考逻辑应该走向何方时遇到了麻烦。
如果您查看下面的 repo,您会发现我在哪里遇到了麻烦。
在此示例中,当有人导航到 /spells/:id 时,它应该将 spell django 模型加载到 redux 存储中,以便全局可访问有关它的信息。
但是我该怎么做呢?我在哪里调用 action 和 reducer 来正确处理状态?
任何指导将不胜感激。
您可以查看完整的项目here。这里有问题的组件是LayoutSpellView (/frontend/src/components/LayoutSpellView)。这就是模型信息存储、显示等的地方。
编辑:添加相关代码
致电componentDidMount:
axios
.get("http://localhost:3000/api/spells/" + spellId)
.then(response => {
let spell = Object.assign({}, spellView.state.spell);
spell.id = response.data.id;
spell.owner = response.data.owner;
...blahblah other fields
this.setState({
spell
});
})
.then(response => {
this.props.dispatch({
type: 'FETCH_SPELL_SUCCESS',
payload: this.state.spell,
});
})
.catch(function(error) {
console.error('[API]\t', error);
});
在LayoutSpellView(与上面相同的组件)
import {loadSpell} from "../src/reducers";
const mapStateToProps = (state) => ({
spell: loadSpell(state.spell.id),
});
const mapDispatchToProps = (dispatch) => ({
getSpell: (state.spell.id) => {
dispatch(loadSpell(state.spell.id))
}
});
动作 spell.js:
export const FETCH_SPELL = '@@spell/FETCH_SPELL';
export const FETCH_SPELL_SUCCESS = '@@spell/FETCH_SPELL_SUCCESS';
export const FETCH_SPELL_FAILURE = '@@spell/FETCH_SPELL_FAILURE';
export const loadSpell = (spellId) => ({
[RSAA]: {
endpoint: '/api/spell/${spellId}',
method: 'GET',
types: [
FETCH_SPELL, FETCH_SPELL_SUCCESS, FETCH_SPELL_FAILURE
]
}
});
减速器 spell.js:
const initialState = {
spell: {
id: 0,
owner: 0,
Name: 'Name',
School: 'unknown',
Subschool: 'unknown',
}
};
export default (state=initialState, action) => {
switch(action.type) {
case spell_action.FETCH_SPELL_SUCCESS:
return {
spell: {
id: action.payload.spell.id,
owner: action.payload.spell.owner,
Name: action.payload.spell.Name,
School: action.payload.spell.School,
Subschool: action.payload.spell.Subschool,
}
};
default:
return state;
}
}
export function loadSpell(state) {
if (state) {
return state.spell
}
}
【问题讨论】:
-
我可能会在组件的
componentDidMount中调用一个操作来检索/存储数据。 -
@NorianNyx 我想了这么多。这实际上是我有一个 axios 调用来检索它的地方。但是在哪里以及如何调用操作以从本地以外的地方推送新状态?
-
您可以在您的 axios 调用的
.then方法中调用它,例如:this.props.dispatch({ type: 'RETRIEVE_SUCCESS', payload: res.data })(或任何您的调度操作模式)。然后在你的减速器中:case 'RETRIEVE_SUCCESS': (state, action) => ({ ...state, action.payload }) -
@NorianNyx 我想我做到了,但它不断给我错误,它是未定义的。我在我的问题中添加了相关的代码。我做得对吗?
-
负载是否未定义?
标签: reactjs redux django-rest-framework react-router jwt