我有一个React应用程序,它使用React-Router / React-Router-dom进行页面导航,并使用redux存储一些全局状态信息(例如django rest框架的jwt令牌)。该州还存储有关当前查看页面的信息,例如序列化的Django模型。
但是,当路线更改时,将Django模型加载到Redux存储的最佳方法是什么?我无法确定逻辑应该去哪里。
如果您在下面查看回购,您会发现我在哪里难以确定。
在此示例中,当某人导航到/spells/:id
时,应将spell
django模型加载到redux存储中,以便可以全局访问有关它的信息。
但是我该怎么做呢?我该在哪里调用动作和减速器以正确处理状态?
任何指导将不胜感激。
您可以查看完整的项目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
]
}
});
Reducers 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
}
}
答案 0 :(得分:0)
让我们以不同的方式看待这个问题。与其问“路由改变时如何调度动作”,不如问“实际的真实来源是什么:Redux或URL?”。
如果我们将redux
作为真理的单一来源,那么那意味着我们需要dispatch
一些action
会造成一些副作用(也许{{1 }}或redux-saga
甚至redux-observable
?)更改了网址:
redux-thunk
如果我们将URL作为真理的唯一来源,则将流程更改为:
Comp -> dispatch(action) -> store updates -> URL changes
如果我们沿着这条路线走,这听起来像您想要的,那么您可能需要连接URL changes -> dispatch(action) -> store updates
,这是以下签名的功能:
middleware
根据您使用的路由器,您可以挂钩他们的动作,也可以挂钩store => next => action => next(action)
并检查下一个URL。无论哪种方式,整个中间件功能都将类似于
window.onpopstate