質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

836閲覧

Expected the reducer to be a functionエラーでreducerが通らない(react-redux)

yamady

総合スコア176

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/02/10 11:00

編集2018/02/11 12:58

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

januswel

2018/02/10 15:15

uiReducer の定義を教えてください
guest

回答2

0

ベストアンサー

App.js の render の中の次の行を削除してみてください。

js

1 const store = createStore(rootReducer, {}, applyMiddleware(ReduxThunk));

store は redux/store.js で作成しているものをそのまま使うとよいです。

投稿2018/02/11 11:13

januswel

総合スコア301

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamady

2018/02/11 12:53

本当にありがとうございます!なるほど、storeをそのまま使えば良かったんですね。やってみた結果、別のエラーが生じてしまい。。泣 Actions must be plain objects. Use custom middleware for async actions. なのですが、これは別ソースの方でconnectしてるからapp.jsで定義しろということなのでしょうが・・・汗
januswel

2018/02/11 12:58

Action がプレインオブジェクトじゃないということで怒られているので、 Action Creator が `return` しているものを確認してみてください。 `type` プロパティを持ったプレインオブジェクトになっていればこのエラーは解決するはずです
yamady

2018/02/14 08:39

ありがとうございます!
guest

0

uiReducer の定義はどうなっていますか ?
多分この定義が関数となっていない可能性があります。

js

1import uiReducer from '../ui/redux/uiReducer';

投稿2018/02/10 15:14

januswel

総合スコア301

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamady

2018/02/11 00:36

いつもありがとうございます。こちらuiReducerおよび読み込んでいるreducerを追記させていただきました。(_ _) ここまでは普通に動いていたのですが。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問