redux에서 AJAX 요청을 만드는 방법
내가 아는 모든 것을 위해 행동 생성 요청을 작성해야합니다. 요청을 제출하기 위해 실행중인 Promise를 사용하는 방법은 무엇입니까? 데이터가 작동 중입니다. 그런 다음 감속기에 새로운 상태가 생성됩니다. 연결 작업과 감속기를 바인딩합니다. 하지만 요청에 promise를 사용하는 방법을 모르겠습니다.
동작
import $ from 'jquery';
export const GET_BOOK = 'GET_BOOK';
export default function getBook() {
return {
type: GET_BOOK,
data: $.ajax({
method: "GET",
url: "/api/data",
dataType: "json"
}).success(function(data){
return data;
})
};
}
감속기
import {GET_BOOK} from '../actions/books';
const booksReducer = (state = initialState, action) => {
switch (action.type) {
case GET_BOOK:
return state;
default:
return state;
}
};
export default booksReducer;
컨테이너 컨테이너에 데이터를 표시하는 방법은 무엇입니까?
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import getBook from '../actions/books';
import Radium from 'radium';
import {Link} from 'react-router';
function mapStateToProps(state) {
return {
books: state.data.books,
};
}
function mapDispatchToProps(dispatch) {
return {
getBooks: () => dispatch(getBook()),
};
}
@Radium
@connect(mapStateToProps, mapDispatchToProps)
class booksPage extends Component {
static propTypes = {
getBooks: PropTypes.func.isRequired,
books: PropTypes.array.isRequired,
};
render() {
const {books} = this.props;
return (
<div>
<Link to={`/authors`}><MUIButton style="flat">All Authors</MUIButton></Link>
<ul>
{books.map((book, index) =>
<li key={index}>
<Link to={`/book/${book.name}`}><MUIButton style="flat"><div class="mui--text-black mui--text-display4">
"{book.name}"</div></MUIButton></Link>
<Link to={`/author/${book.author}`}><MUIButton style="flat"><div class="mui--text-black mui--text-display4">
{book.author}</div></MUIButton></Link>
</li>
)}
</ul>
</div>
);
}
}
export default booksPage;
이미 redux를 사용 redux-thunk
하고 있으므로 비동기 작업을 정의 할 수있는 미들웨어를 적용 할 수 있습니다 .
설치 및 사용 : Redux-thunk
export function fetchBook(id) {
return dispatch => {
dispatch(setLoadingBookState()); // Show a loading spinner
fetch(`/book/${id}`, (response) => {
dispatch(doneFetchingBook()); // Hide loading spinner
if(response.status == 200){
dispatch(setBook(response.json)); // Use a normal function to set the received state
}else {
dispatch(someError)
}
})
}
}
function setBook(data) {
return { type: 'SET_BOOK', data: data };
}
Redux 문서에 설명 된 비동기 작업을 사용해야합니다.
다음은 비동기 작업을위한 감속기의 예입니다.
const booksReducer = (state = {}, action) => {
switch (action.type) {
case 'RESOLVED_GET_BOOK':
return action.data;
default:
return state;
}
};
export default booksReducer;
그런 다음 비동기 작업을 만듭니다.
export const getBook() {
return fetch('/api/data')
.then(response => response.json())
.then(json => dispatch(resolvedGetBook(json)))
}
export const resolvedGetBook(data) {
return {
type: 'RESOLVED_GET_BOOK',
data: data
}
}
몇 가지 참고 :
- redux-thunk 미들웨어를 사용하여 Promise (Object 대신)를 반환 할 수 있습니다.
- jQuery ajax 라이브러리를 사용하지 마십시오. 이를 위해 특별히 다른 라이브러리를 사용하십시오 (예 : fetch ()). 내가 사용 Axios의 HTTP 클라이언트를 .
- redux에서는 감속기에서만 순수 기능을 사용한다는 것을 기억하십시오. 감속기 내부에서 ajax 호출을하지 마십시오.
- redux 문서에서 전체 가이드를 읽으십시오.
dispatch
콜백 내에서 사용할 수 있어야합니다 (인수로 전달하는 경우).
export default function getBook(dispatch) {
$.ajax({
method: "GET",
url: "/api/data",
dataType: "json"
}).success(function(data){
return dispatch({type:'GET_BOOK', data: data});
});
}
그런 다음 dispatch
조치로 전달 하십시오.
function mapDispatchToProps(dispatch) {
return {
getBooks: () => getBook(dispatch),
};
}
이제 action.data
감속기 의 속성에 액세스 할 수 있어야합니다 .
const booksReducer = (state = initialState, action) => {
switch (action.type) {
case GET_BOOK:
//action.data <--- here
return state;
default:
return state;
}
};
액션 제작자를 "순수"하게 유지하기 위해 우려 사항을 분리 할 수 있습니다.
해결책; 미들웨어를 작성하십시오. 예를 들어 (수퍼 에이전트 사용) 이것을 사용하십시오.
import Request from 'superagent';
const successHandler = (store,action,data) => {
const options = action.agent;
const dispatchObject = {};
dispatchObject.type = action.type + '_SUCCESS';
dispatchObject[options.resourceName || 'data'] = data;
store.dispatch(dispatchObject);
};
const errorHandler = (store,action,err) => {
store.dispatch({
type: action.type + '_ERROR',
error: err
});
};
const request = (store,action) => {
const options = action.agent;
const { user } = store.getState().auth;
let method = Request[options.method];
method = method.call(undefined, options.url)
if (user && user.get('token')) {
// This example uses jwt token
method = method.set('Authorization', 'Bearer ' + user.get('token'));
}
method.send(options.params)
.end( (err,response) => {
if (err) {
return errorHandler(store,action,err);
}
successHandler(store,action,response.body);
});
};
export const reduxAgentMiddleware = store => next => action => {
const { agent } = action;
if (agent) {
request(store, action);
}
return next(action);
};
이 모든 것을 모듈에 넣으십시오.
이제 'auth'라는 액션 생성자가있을 수 있습니다.
export const auth = (username,password) => {
return {
type: 'AUTHENTICATE',
agent: {
url: '/auth',
method: 'post',
resourceName: 'user',
params: {
username,
password
}
}
};
};
The property 'agent' will be picked up by the middleware, which sends the constructed request over the network, then dispatches the incoming result to your store.
Your reducer handles all this, after you define the hooks:
import { Record } from 'immutable';
const initialState = Record({
user: null,
error: null
})();
export default function auth(state = initialState, action) {
switch (action.type) {
case 'AUTHENTICATE':
return state;
case 'AUTHENTICATE_SUCCESS':
return state.merge({ user: action.user, error: null });
case 'AUTHENTICATE_ERROR':
return state.merge({ user: null, error: action.error });
default:
return state;
}
};
Now inject all this into your view logic. I'm using react as an example.
import React from 'react';
import ReactDOM from 'react-dom';
/* Redux + React utils */
import { createStore, applyMiddleware, bindActionCreators } from 'redux';
import { Provider, connect } from 'react-redux';
// thunk is needed for returning functions instead
// of plain objects in your actions.
import thunkMiddleware from 'redux-thunk';
// the logger middleware is useful for inspecting data flow
import createLogger from 'redux-logger';
// Here, your new vital middleware is imported
import { myNetMiddleware } from '<your written middleware>';
/* vanilla index component */
import _Index from './components';
/* Redux reducers */
import reducers from './reducers';
/* Redux actions*/
import actionCreators from './actions/auth';
/* create store */
const store = createStore(
reducers,
applyMiddleware(
thunkMiddleware,
myNetMiddleware
)
);
/* Taint that component with store and actions */
/* If all goes well props should have 'auth', after we are done */
const Index = connect( (state) => {
const { auth } = state;
return {
auth
};
}, (dispatch) => {
return bindActionCreators(actionCreators, dispatch);
})(_Index);
const provider = (
<Provider store={store}>
<Index />
</Provider>
);
const entryElement = document.getElementById('app');
ReactDOM.render(provider, entryElement);
All of this implies you already set up a pipeline using webpack,rollup or something, to transpile from es2015 and react, to vanilla js.
참고URL : https://stackoverflow.com/questions/33891669/how-to-make-ajax-request-in-redux
'programing tip' 카테고리의 다른 글
arduino 환경에서 라이브러리를 어떻게 제거합니까? (0) | 2020.11.28 |
---|---|
Golang은 가변 기능을 지원합니까? (0) | 2020.11.28 |
왜 C ++ 옵티마이 저가 이러한 임시 변수에 문제가 있거나 타이트 루프에서`v []`를 피해야합니까? (0) | 2020.11.28 |
.NET 단위 테스트 패키지? (0) | 2020.11.28 |
git-svn이 특정 svn 브랜치를 원격 저장소로 사용하게하려면 어떻게해야합니까? (0) | 2020.11.28 |