代码之家  ›  专栏  ›  技术社区  ›  cclloyd

在路由加载时将模型加载到redux store的最佳方法

  •  1
  • cclloyd  · 技术社区  · 7 年前

    但是当路由改变时,将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);
        });
    

    (与上述部件相同)

    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))
        }
    });
    

    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
            ]
        }
    });
    

    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
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Tim Roberts    7 年前

    让我们换个角度看这个问题。与其问“当路由改变时如何调度操作”,不如问“真相的真正来源是什么:Redux还是URL?”

    如果我们一起去 redux dispatch 一些 action 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)
    

    根据您使用的路由器,您可以钩住它们的动作,也可以钩住它们 window.onpopstate 然后检查下一个url。不管怎样,整个中间件功能看起来像

    const middleware = store => {
      return next => action => {
        if (actionWillCauseSpellToBeNeeded(action)) {
           makeAPICall()
             .then(transformAPIToAction)
             .catch(transformError)
             .then(store.dispatch) 
        }
        return next(action)
      }
    }
    
    推荐文章