React Nativeでスマートフォン専用のアプリを開発しています。
App.jsにてcreateStoreを設定しようとしているのですが、下記のエラーが出てしまい通らずに困っています。
アプリの内容は雇用者を管理して、情報を投稿するアプリを想定しています。
Expected the reducer to be a function
ソースコード
App.js
JavaScript
1import React from 'react'; 2import { StyleSheet, View } from 'react-native'; 3import { createStore, applyMiddleware } from 'redux'; 4import firebase from 'react-native-firebase'; 5import { GoogleSignin } from 'react-native-google-signin'; 6import { Provider } from 'react-redux'; 7import ReduxThunk from 'redux-thunk'; 8 9import { GOOGLE_SIGN_IN_ANDROID_CLIENT_ID, GOOGLE_SIGN_IN_IOS_CLIENT_ID } from './config'; 10import { store, rootReducer } from './redux/store'; 11 12import LoadingModal from './ui/components/LoadingModal'; 13import LoggedIn from './loggedin/screens'; 14import LoggedOut from './loggedout/screens'; 15 16GoogleSignin.configure({ 17 iosClientId: GOOGLE_SIGN_IN_IOS_CLIENT_ID, 18 webClientId: GOOGLE_SIGN_IN_ANDROID_CLIENT_ID, 19}); 20 21const styles = StyleSheet.create({ 22 container: { 23 flex: 1, 24 }, 25}); 26 27type State = { 28 loading: boolean, 29 user?: Object, 30} 31 32export default class App extends React.Component<*, State> { 33 authSubscription: () => any; 34 state: State; 35 36 constructor() { 37 super(); 38 this.state = { 39 loading: true, 40 }; 41 } 42 43 componentDidMount() { 44 this.authSubscription = firebase.auth().onAuthStateChanged((user) => { 45 this.setState({ 46 loading: false, 47 user, 48 }); 49 50 firebase.analytics().setUserId(user ? user.uid : null); 51 }); 52 } 53 54 componentWillUnmount() { 55 this.authSubscription(); 56 } 57 58 render() { 59 const store = createStore(rootReducer, {}, applyMiddleware(ReduxThunk)); 60 if (this.state.loading) return null; 61 62 return ( 63 <Provider store={store}> 64 <View style={styles.container}> 65 <LoadingModal /> 66 {this.state.user ? <LoggedIn /> : <LoggedOut />} 67 </View> 68 </Provider> 69 ); 70 } 71}
redux/store.js
JavaScript
1import { createStore, combineReducers } from 'redux'; 2import { reducer as formReducer } from 'redux-form'; 3 4import uiReducer from '../ui/redux/uiReducer'; 5import employeeFormReducer from '../ui/redux/employeeFormReducer'; 6import employeeReducer from '../ui/redux/employeeReducer'; 7 8const rootReducer = combineReducers({ 9 form: formReducer, 10 ui: uiReducer, 11 employeeForm: employeeFormReducer, 12 employees: employeeReducer 13}); 14 15const store = createStore(rootReducer); 16export default store;
試してみたこと
rootReducerの部分をstoreに変えてみたりもしました。
追記
reduxを読み込んでいるスクリプトを追記します。
uiReducer.js
JavaScript
1type UiAction = { 2 type: 'ui/loading/hide' | 'ui/loading/show', 3} 4 5type UiReduxState = { 6 loading: boolean, 7} 8 9const initialState = { 10 loading: false, 11}; 12 13export default (state: UiReduxState = initialState, action: UiAction): UiReduxState => { 14 switch (action.type) { 15 case 'ui/loading/hide': 16 return { 17 ...state, 18 loading: false, 19 }; 20 21 case 'ui/loading/show': 22 return { 23 ...state, 24 loading: true, 25 }; 26 27 default: 28 return state; 29 } 30}; 31 32const isLoading = (state: { ui: UiReduxState }) => state.ui.loading; 33 34export const Store = ({ 35 isLoading, 36});
employeeForm.js
JavaScript
1type UiAction = { 2 type: 'employee_update', 3 type: 'employee_create' 4} 5 6const initialState = { 7 title: '', 8 category: '', 9 address: '', 10 price: '' 11}; 12 13export default (state = initialState, action) => { 14 switch (action.type) { 15 case 'employee_update': 16 return {...state, [action.payload.prop]: action.payload.value }; 17 case 'employee_create': 18 return initialState; 19 default: 20 return state; 21 } 22};
employeeReducer.js
JavaScript
1type UiAction = { 2 type: 'employees_fetch_success', 3} 4 5const initialState = {}; 6 7export default (state = initialState, action) => { 8 switch (action.type) { 9 case 'employees_fetch_success': 10 return action.payload; 11 default: 12 return state; 13 } 14};
追記②
ご指摘いただいたようにすると、どうやらredux部分は解決したように思えるのですが(ありがとうございます!)根本的なエラーはこちらであったようなきがします。
JavaScript
1Actions must be plain objects. Use custom middleware for async actions.
もしかしたら、自分の書き方がひどすぎるのかもしれません(涙
エラーの続き
This error is located at: in Home (created by Connect(Home)) in Connect(Home) (at SceneView.js:31) in SceneView (at CardStack.js:405) in RCTView (at View.js:71) in View (at createAnimatedComponent.js:147) in AnimatedComponent (at Card.js:26) in Card (at PointerEventsContainer.js:55) in Container (at CardStack.js:436) in RCTView (at View.js:71) ・・・
ソースコード
Home.js
import _ from 'lodash'; import React from 'react'; import { connect } from 'react-redux'; import { ListView, Image, Text, View, StyleSheet } from 'react-native'; import Screen from '../../ui/components/Screen'; import { employeesFetch } from '../../ui/redux/uiActions'; const styles = StyleSheet.create({ }); class Home extends React.Component { // Set the navigation options for `react-navigation` static navigationOptions = { headerTitle: 'Home', }; componentWillMount() { this.props.employeesFetch(); this.createDataSource(this.props); } componentWillReceiveProps(nextProps) { this.createDataSource(nextProps); } createDataSource({ employees }) { const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !==r2 }); this.dataSource = ds.cloneWithRows(employees); } render() { console.log(this.props); return ( <Screen> <View> <Text>Employee List</Text> <Text>Employee List</Text> <Text>Employee List</Text> <Text>Employee List</Text> </View> </Screen> ); } } const mapStateToProps = state => { const employees = _.map(state.employees, (val, uid) => { return { ...val, uid }; }); return { employees }; } export default connect(mapStateToProps, { employeesFetch })(Home);
回答2件
あなたの回答
tips
プレビュー