Skip to content

跳转路径 ​

本节目标:理解“跳转路径”的核心思路,并能把它用于实际开发或面试表达。 使用

6.1.1 src\index.js
src\index.js
import React from 'react';import dva, { connect } from './dva';+import { Router, Route,Link,routerRedux } from './dva/router';+import { ConnectedRouter } from 'connected-react-router';const app = dva();app.model({    namespace: 'counter',    state: { number: 0 },    reducers: {        add(state) {            return { number: state.number + 1 };        }    },    effects: {        *asyncAdd(action, { call, put }) {            yield call(delay, 1000);            yield put({ type: 'counter/add' });        },+       *goto({ to }, { put }) {+          yield put(routerRedux.push(to));+       }}});function Counter(props) {    return (        <div>            <p>{props.number}</p>            <button onClick={() => props.dispatch({ type: "counter/add" })}>+</button>            <button onClick={() => props.dispatch({ type: "counter/asyncAdd" })}>

异步

+</button>+            <button onClick={() => props.dispatch({ type: "counter/goto", to: '/' })}>

跳转到

/</button></div>    )}const ConnectedCounter = connect(    (state) => state.counter)(Counter);const Home = () => <div>Home</div>app.router((api) => (+    <ConnectedRouter  history={api.history}><>            <Link to="/">Home</Link>            <Link to="/counter">Counter</Link>            <Route path="/" exact={true} component={Home} />            <Route path="/counter" component={ConnectedCounter} />        </>    </ConnectedRouter >));app.start('#root');
function delay(ms) {    return new Promise((resolve) => {        setTimeout(function () {            resolve();        }, ms);    });}
6.2

实现


6.2.1 dva\index.js
src\dva\index.js
import React from 'react';import ReactDOM from 'react-dom';import { createStore, combineReducers, applyMiddleware } from 'redux';import createSagaMiddleware from 'redux-saga';import * as sagaEffects from 'redux-saga/effects';import { NAMESPACE_SEP } from './constants';import { connect, Provider } from 'react-redux';import prefixNamespace from './prefixNamespace';import { createHashHistory } from 'history';+import { routerMiddleware, connectRouter, ConnectedRouter } from "connected-react-router";let history = createHashHistory();export { connect };
function dva() {    const app = {        _models: [],        model,        router,        _router: null,        start    }+    const initialReducers = { router: connectRouter(history) };function model(model) {        const prefixedModel = prefixNamespace(model);        app._models.push(prefixedModel);        return prefixedModel;    }    function router(router) {        app._router = router;    }
function start(root) {        for (const model of app._models) {            initialReducers[model.namespace] = getReducer(model);        }        let rootReducer = createReducer();        const sagas = getSagas(app);        const sagaMiddleware = createSagaMiddleware();+        let store = createStore(rootReducer, applyMiddleware(routerMiddleware(history), sagaMiddleware));sagas.forEach(saga => sagaMiddleware.run(saga));        ReactDOM.render(<Provider store={store}>{app._router({ history })}</Provider>, document.querySelector(root))        function createReducer() {            return combineReducers(initialReducers);        }    }    function getSagas(app) {        let sagas = [];        for (const model of app._models) {            sagas.push(getSaga(model.effects, model));        }        return sagas;    }    return app;}function getSaga(effects, model) {    return function* () {        for (const key in effects) {            const watcher = getWatcher(key, model.effects[key], model);            yield sagaEffects.fork(watcher);        }    };}function getWatcher(key, effect, model) {    return function* () {        yield sagaEffects.takeEvery(key, function* sagaWithCatch(...args) {            yield effect(...args, { ...sagaEffects, put: action => sagaEffects.put({ ...action, type: prefixType(action.type, model) }) });        });    };}function prefixType(type, model) {    if (type.indexOf('/') === -1) {return `${model.namespace}${NAMESPACE_SEP}${type}`;    }    return type;}function getReducer(model) {    let { reducers, state: defaultState } = model;    let reducer = (state = defaultState, action) => {        let reducer = reducers[action.type];        if (reducer) {            return reducer(state, action);        }        return state;    }    return reducer;}
export default dva;
6.2.2 src\dva\router.js
src\dva\router.js
import * as routerRedux from 'connected-react-router';export * from 'react-router-dom';export {    routerRedux}

> 来自

 <http://www.zhufengpeixun.com/strong/html/106.8.dva.html>

本站总访问 — 次