2016-08-02 4 views
12

私はExpressとWebpackと共にReactJS + Reduxを使用しています。 APIが構築されているので、クライアント側からREST呼び出し(GET、POST、PUT、DELETE)を実行できるようにしたいと考えています。ReactJS + ReduxアプリケーションからREST呼び出しを正しく行う方法は?

Reduxアーキテクチャでは、どのように適切に行うべきでしょうか?減速者、アクションクリエイター、店舗、およびルートに応じた流れの良い例は非常に役立ちます。

ありがとうございます!

答えて

10

最も簡単な方法は、redux-thunkパッケージを使用することです。これはあなたが定期的にsyncアクションと一緒にasyncアクションを派遣することができます

import { createStore, applyMiddleware } from 'redux'; 
import thunk from 'redux-thunk'; 
import rootReducer from './reducers/index'; 

const store = createStore(
    rootReducer, 
    applyMiddleware(thunk) 
); 

:このパッケージにはとてもまず、あなたはReduxのにそれを接続する必要があり、Reduxのミドルウェアです。それらのうちの1つを作成しましょう:プレゼンテーションコンポーネントとコンテナコンポーネントの反応コンポーネントを分離することをお勧めします。このアプローチは、this articleに完全に記載されています。

次に、コンポーネントを作成して、プレゼンテーション用のTodosコンポーネントにデータを提供する必要があります。あなたが表示ローダ/エラーメッセージをしたい場合はFETCH_TODOS_SUCCESSアクションを処理します

// TodosContainer.js 

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
import { fetchTodos } from '../actions'; 

class TodosContainer extends Component { 
    componentDidMount() { 
    // When container was mounted, we need to start fetching todos. 
    this.props.fetchTodos(); 
    } 

    render() { 
    // In some simple cases, it is not necessary to create separate `Todos` component. You can put todos markup directly here. 
    return <Todos items={this.props.todos} /> 
    } 
} 

// This function is used to convert redux global state to desired props. 
function mapStateToProps(state) { 
    // `state` variable contains whole redux state. 
    return { 
    // I assume, you have `todos` state variable. 
    // Todos will be available in container component as `this.props.todos` 
    todos: state.todos 
    }; 
} 

// This function is used to provide callbacks to container component. 
function mapDispatchToProps(dispatch) { 
    return { 
    // This function will be available in component as `this.props.fetchTodos` 
    fetchTodos: function() { 
     dispatch(fetchTodos()); 
    } 
    }; 
} 

// We are using `connect` function to wrap our component with special component, which will provide to container all needed data. 
export default connect(mapStateToProps, mapDispatchToProps)(TodosContainer); 

また、あなたがtodosReducerを作成する必要があり、そして他の2つのアクション:ここでは、我々はreact-reduxライブラリを使用しています。

// reducers.js 

import { combineReducers } from 'redux'; 

const INITIAL_STATE = { 
    items: [], 
    isFetching: false, 
    error: undefined 
}; 

function todosReducer(state = INITIAL_STATE, action) { 
    switch (action.type) { 
    case 'FETCH_TODOS_REQUEST': 
     // This time, you may want to display loader in the UI. 
     return Object.assign({}, state, { 
     isFetching: true 
     }); 
    case 'FETCH_TODOS_SUCCESS': 
     // Adding derived todos to state 
     return Object.assign({}, state, { 
     isFetching: false, 
     todos: action.todos 
     }); 
    case 'FETCH_TODOS_FAILURE': 
     // Providing error message to state, to be able display it in UI. 
     return Object.assign({}, state, { 
     isFetching: false, 
     error: action.error 
     }); 
    default: 
     return state; 
    } 
} 

export default combineReducers({ 
    todos: todosReducer 
}); 
CREATEのような他の操作について

UPDATEDELETE何も特別なことは、彼らが同じように実装している、存在しません。

+0

ありがとうございました。まだそのコンセプトを把握しようとしています。どのようにしてコンポーネントからアクションを呼び出すのですか?また、 '.then(response => response.json()。then(body =>({response、body}))))) .then(({response、body})=> {お返事を –

+0

@JoKo、はい、すぐに回答を更新します。 – 1ven

+0

@JoKo、更新された回答 – 1ven

0

redux-thunk,redux-sagaredux-observableなどのライブラリの主な使用例です。

import fetch from 'isomorphic-fetch' 

export const REQUEST_POSTS = 'REQUEST_POSTS' 
function requestPosts(subreddit) { 
    return { 
    type: REQUEST_POSTS, 
    subreddit 
    } 
} 

export const RECEIVE_POSTS = 'RECEIVE_POSTS' 
function receivePosts(subreddit, json) { 
    return { 
    type: RECEIVE_POSTS, 
    subreddit, 
    posts: json.data.children.map(child => child.data), 
    receivedAt: Date.now() 
    } 
} 

// Meet our first thunk action creator! 
// Though its insides are different, you would use it just like any other action creator: 
// store.dispatch(fetchPosts('reactjs')) 

export function fetchPosts(subreddit) { 

    // Thunk middleware knows how to handle functions. 
    // It passes the dispatch method as an argument to the function, 
    // thus making it able to dispatch actions itself. 

    return function (dispatch) { 

    // First dispatch: the app state is updated to inform 
    // that the API call is starting. 

    dispatch(requestPosts(subreddit)) 

    // The function called by the thunk middleware can return a value, 
    // that is passed on as the return value of the dispatch method. 

    // In this case, we return a promise to wait for. 
    // This is not required by thunk middleware, but it is convenient for us. 

    return fetch(`http://www.reddit.com/r/${subreddit}.json`) 
     .then(response => response.json()) 
     .then(json => 

     // We can dispatch many times! 
     // Here, we update the app state with the results of the API call. 

     dispatch(receivePosts(subreddit, json)) 
    ) 

     // In a real world app, you also want to 
     // catch any error in the network call. 
    } 
} 

上記の例では、http://redux.js.org/docs/advanced/AsyncActions.htmlから直接取得されて、本当にあなたの質問に答えのための決定的なソースです:あなたはこのような何かをする場所

redux-thunkは、最も簡単です。

+0

Thunkは何をしているのでしょうか?任意のライブラリを使わずにAPIのURLにfetch()をするだけのようです。 –

+0

'redux-thunk'は非同期的な振る舞いをreduxに統合するために構造的に有用です。これは同期的です。 'fetch'はネットワーク呼び出しには十分ですが、簡単なことです。あなたがreduxアプリケーションからの呼び出しを行う方法を尋ねるときは、あなたのreduxアーキテクチャにその動作を組み込むために、 'redux-thunk'のようなものが必要です。 –

+0

は本当に明確化を感謝します!フェッチは別の言葉では正しいですか?次に、POST、PUT、およびDELETEは何ですか? –

1

短い答えは:

  1. reduxがあなたが任意のライブラリを使用することができますアーキテクチャ
  2. ではありません。最近多くの人がfetch APIを直接使用しています。
  3. reduxを非同期アクション(AJAXに必要)と統合できるようにするには、ライブラリを使用して支援する必要があります。最も普及しているのは、redux-thunkredux-sagaです。

あなたのreduxアプリケーションにドロップできる脳死の単純なライブラリについては、redux-crud-storeを試すことができます。免責事項:私はそれを書いた。fetch APIや他のAPIクライアントをredux-sagaと統合することに興味がある場合は、redux-crud-storeのソースも読むことができます

関連する問題