请考虑以下代码:
/**
* OTHER IMPORTS...
*/
import React, {Component} from 'react';
import {connect, Provider} from 'react-redux';
import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
import firebase from 'firebase';
/**
* Connected Router - Flux Router with Connected Redux
*/
const ReduxRouter = connect()(Router);
class MyApp extends Component {
// Many Methods
/**
*
*/
componentWillMount () {
firebase.initializeApp({});
firebase.auth().onAuthStateChanged(this.onAuthStateChangedCallback.bind(this));
if (!this.reducers) {
this.reducers = combineReducers({
... // Many Reducers for other Scenes
});
}
if (!this.store) {
this.store = compose(applyMiddleware(ReduxThunk))(createStore)(this.reducers);
}
}
/**
*
*/
onAuthStateChangedCallback (user) {
if (user) {
/*
// TODO DISPATCH <------ Here is my problem
dispatch({
type: 'LOGGED',
payload: user
});
*/
Actions.First();
} else {
this.setState({
isLoading: false,
loggedIn: false
});
Actions.LogIn();
}
}
render () {
return (
<Provider store={this.store}>
<ReduxRouter sceneStyle={{paddingTop: 0, backgroundColor: '#FFFFFF'}}>
<Scene key="Menu" component={MenuScene} open={false} type={ActionConst.REPLACE} passProps>
{/* MANY OTHERS SCENES */}
<Scene key="First" title="First" type={ActionConst.REPLACE} component={FirstScene} passProps />
<Scene key="LogIn" title="LogIn" type={ActionConst.REPLACE} component={LogInScene} passProps />
</Scene>
</ReduxRouter>
</Provider>
);
}
}
export default MyApp
我的所有场景&#34;菜单&#34;,包括它是连接组件
const mapStateToProps = (state) => {
return {
...state.First
};
};
export default connect(mapStateToProps, {
... // Actions
})(First);
我决定在主要组件中设置firebase auth回调。有一种情况我需要调度一些动作,所以我的所有场景都会读取在这种情况下应该调度的数据。
所以,问题是:有没有办法在连接组件外调用调度,或者是连接&#34; MyApp&#34;成分
答案 0 :(得分:2)
一些事情。
首先,理想情况下,您应该在组件层次结构中创建商店 ,通常是在应用程序入口点。例如:
// index.js
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
其次,您可以通过组件层次结构将dispatch
作为prop传递,或者只是连接其他组件。基本上,任何想要与商店交互的组件都应使用connect()
。如果您未将mapDispatchToProps
函数传入connect
,您的组件将自动获得props.dispatch
。
答案 1 :(得分:1)
很棒的方法!除了你的建议,我查看了docs,最后得到了index.js
的这个结构。我认为代码本身解释了结构。再次感谢您的帮助!
/**
* Modules dependencies
*/
import React, {Component} from 'react';
import {AppState} from 'react-native';
import {connect, Provider} from 'react-redux';
import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
import ReduxThunk from 'redux-thunk';
import {Scene, Router, ActionConst, Actions} from 'react-native-router-flux';
import firebase from 'firebase';
/**
* Internal dependencies
*/
import {default as MyScene1Reducer} from './MyScene1/reducer';
import {default as MyScene2Reducer} from './MyScene2/reducer';
import {default as MyScene3Reducer} from './MyScene3/reducer';
import {default as MyScene1} from './MyScene1';
import {default as MyScene2} from './MyScene2';
import {default as MyScene3} from './MyScene3';
/**
* Firebase
*/
firebase.initializeApp({
apiKey: '',
authDomain: '',
databaseURL: '',
storageBucket: '',
messagingSenderId: ''
});
/**
* Scenes
*/
const Scenes = Actions.create(
<Scene key="Menu" component={MenuScene} open={false} type={ActionConst.REPLACE} passProps>
<Scene key="MyScene1" title="MyScene1" type={ActionConst.REPLACE} component={MyScene1} passProps />
<Scene key="MyScene2" title="MyScene2" type={ActionConst.REPLACE} component={MyScene2} passProps />
<Scene key="MyScene3" title="MyScene3" type={ActionConst.REPLACE} component={MyScene3} passProps />
</Scene>
);
const ReduxRouter = connect()(Router);
const Reducers = combineReducers({
MyScene1: MyScene1Reducer,
MyScene2: MyScene2Reducer,
MyScene3: MyScene3Reducer
});
const Store = compose(applyMiddleware(ReduxThunk))(createStore)(Reducers);
/**
* The Main Component - View
*/
class MyApp extends Component {
/**
*
*/
constructor(props) {
super(props);
this.state = {
};
}
/**
*
*/
componentWillMount () {
firebase.auth().onAuthStateChanged(this.onAuthStateChangedCallback.bind(this));
}
/**
*
*/
componentDidMount () {
AppState.addEventListener('change', this.onAppStateChangeCallback);
}
/**
*
*/
componentWillUnmount() {
AppState.removeEventListener('change', this.onAppStateChangeCallback);
}
/**
*
*/
onAppStateChangeCallback = (nextAppState) => {
console.log(nextAppState);
}
/**
*
*/
onAuthStateChangedCallback (user) {
if (user) {
console.log(this.props.dispatch); <---- Exists!
Actions.MyScene2();
} else {
Actions.MyScene3();
}
}
/**
*
*/
render () {
return (
<ReduxRouter scenes={Scenes} sceneStyle={{paddingTop: 0, backgroundColor: '#FFFFFF'}} />
);
}
}
/**
* The Main Component - Provider / Store
*/
const MyAppStore = () => {
const MyAppConnected = connect()(MyApp);
return (
<Provider store={Store}>
<MyAppConnected />
</Provider>
);
};
export default MyAppStore;