我从服务器获得令牌认证,所以当我最初加载我的Redux应用程序时,我需要向该服务器发出请求以检查用户是否经过身份验证,如果是,我应该获得令牌.
我发现不建议使用Redux核心INIT操作,那么在呈现应用程序之前如何调度操作呢?
Ser*_*iuk 65
您可以在Root componentDidMount方法中调度操作,在render方法中可以验证身份验证状态.
像这样的东西:
class App extends Component {
componentDidMount() {
this.props.getAuth()
}
render() {
return this.props.isReady
? <div> ready </div>
: <div>not ready</div>
}
}
const mapStateToProps = (state) => ({
isReady: state.isReady,
})
const mapDispatchToProps = {
getAuth,
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
Run Code Online (Sandbox Code Playgroud)
Chr*_*emp 27
对于为此提出的任何解决方案,我都不满意,然后我想到我正在考虑需要渲染的类.如果我刚刚为启动创建了一个类,然后将东西推入componentDidMount方法并让render显示器加载屏幕呢?
<Provider store={store}>
<Startup>
<Router>
<Switch>
<Route exact path='/' component={Homepage} />
</Switch>
</Router>
</Startup>
</Provider>
Run Code Online (Sandbox Code Playgroud)
然后有这样的事情:
class Startup extends Component {
static propTypes = {
connection: PropTypes.object
}
componentDidMount() {
this.props.actions.initialiseConnection();
}
render() {
return this.props.connection
? this.props.children
: (<p>Loading...</p>);
}
}
function mapStateToProps(state) {
return {
connection: state.connection
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(Actions, dispatch)
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Startup);
Run Code Online (Sandbox Code Playgroud)
然后编写一些redux操作以异步初始化您的应用程序.工作一种享受.
更新:这个答案是针对React Router 3的
我使用react-router onEnter props 解决了这个问题.这是代码的样子:
// this function is called only once, before application initially starts to render react-route and any of its related DOM elements
// it can be used to add init config settings to the application
function onAppInit(dispatch) {
return (nextState, replace, callback) => {
dispatch(performTokenRequest())
.then(() => {
// callback is like a "next" function, app initialization is stopped until it is called.
callback();
});
};
}
const App = () => (
<Provider store={store}>
<IntlProvider locale={language} messages={messages}>
<div>
<Router history={history}>
<Route path="/" component={MainLayout} onEnter={onAppInit(store.dispatch)}>
<IndexRoute component={HomePage} />
<Route path="about" component={AboutPage} />
</Route>
</Router>
</div>
</IntlProvider>
</Provider>
);
Run Code Online (Sandbox Code Playgroud)
这里所有的答案似乎都是创建根组件并将其在componentDidMount中触发的变体。我最喜欢redux的一件事是,它使数据获取与组件生命周期脱钩。我认为没有理由在这种情况下应该有所不同。
如果要将商店导入到根index.js文件中,则可以initScript()在该文件中调度动作创建者(我们称其为),它将在加载任何内容之前触发。
例如:
//index.js
store.dispatch(initScript());
ReactDOM.render(
<Provider store={store}>
<Routes />
</Provider>,
document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)
如果您使用的是React Hooks,则一种解决方案是:
useEffect(() => store.dispatch(handleAppInit()), []);
Run Code Online (Sandbox Code Playgroud)
空数组将确保在第一次渲染时仅调用一次。
完整示例:
import React, { useEffect } from 'react';
import { Provider } from 'react-redux';
import AppInitActions from './store/actions/appInit';
function App() {
useEffect(() => store.dispatch(AppInitActions.handleAppInit()), []);
return (
<Provider store={store}>
<div>
Hello World
</div>
</Provider>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
使用redux-saga中间件你可以做得很好。
只需定义一个 saga,它在被触发之前不监视已调度的动作(例如 withtake或takeLatest)。当fork像这样从 root saga ed 时,它将在应用程序启动时只运行一次。
下面是一个不完整的例子,它需要一些关于redux-saga包的知识,但说明了这一点:
传奇/launchSaga.js
import { call, put } from 'redux-saga/effects';
import { launchStart, launchComplete } from '../actions/launch';
import { authenticationSuccess } from '../actions/authentication';
import { getAuthData } from '../utils/authentication';
// ... imports of other actions/functions etc..
/**
* Place for initial configurations to run once when the app starts.
*/
const launchSaga = function* launchSaga() {
yield put(launchStart());
// Your authentication handling can go here.
const authData = yield call(getAuthData, { params: ... });
// ... some more authentication logic
yield put(authenticationSuccess(authData)); // dispatch an action to notify the redux store of your authentication result
yield put(launchComplete());
};
export default [launchSaga];
Run Code Online (Sandbox Code Playgroud)
上述信函的代码launchStart和launchComplete你应该创建终极版动作。创建这样的操作是一种很好的做法,因为它们可以派上用场,以便在启动或完成时通知状态执行其他操作。
然后你的根传奇应该分叉这个launchSaga传奇:
传奇/ index.js
import { fork, all } from 'redux-saga/effects';
import launchSaga from './launchSaga';
// ... other saga imports
// Single entry point to start all sagas at once
const root = function* rootSaga() {
yield all([
fork( ... )
// ... other sagas
fork(launchSaga)
]);
};
export default root;
Run Code Online (Sandbox Code Playgroud)
请阅读redux-saga非常好的文档以获取更多信息。
| 归档时间: |
|
| 查看次数: |
46813 次 |
| 最近记录: |