플럭스 앱에서 어디에 아약스 요청을 해야 합니까?
플럭스 아키텍처로 react.js 어플리케이션을 만들고 있는데 서버로부터의 데이터 요구 장소와 타이밍을 파악하고 있습니다.이에 대한 예가 있습니까?(TODO 앱 아님)
저는 비동기 쓰기 작업을 작업 작성자에 넣고 비동기 읽기 작업을 스토어에 넣는 것을 적극 지지합니다.목표는 스토어 상태 수정 코드를 완전히 동기화된 액션핸들러로 유지하는 것입니다.이것에 의해, 간단하게 추론할 수 있어 유닛 테스트도 간단하게 실시할 수 있습니다.동일한 엔드포인트에 대한 여러 동시 요청을 방지하기 위해(예: 이중 읽기) 실제 요청 처리를 여러 요청을 방지하는 약속을 사용하는 별도의 모듈로 이동합니다. 예를 들어 다음과 같습니다.
class MyResourceDAO {
get(id) {
if (!this.promises[id]) {
this.promises[id] = new Promise((resolve, reject) => {
// ajax handling here...
});
}
return this.promises[id];
}
}
스토어 내 읽기에는 비동기 기능이 포함되지만 스토어는 비동기 핸들러에서 자신을 업데이트하지 않고 대신 액션을 실행하고 응답이 도착했을 때만 액션을 실행한다는 중요한 경고가 있습니다.이 액션의 핸들러는 실제 상태 변경을 하게 됩니다.
예를 들어 컴포넌트는 다음 작업을 수행합니다.
getInitialState() {
return { data: myStore.getSomeData(this.props.id) };
}
매장에는 다음과 같은 방법이 구현되어 있을 것입니다.
class Store {
getSomeData(id) {
if (!this.cache[id]) {
MyResurceDAO.get(id).then(this.updateFromServer);
this.cache[id] = LOADING_TOKEN;
// LOADING_TOKEN is a unique value of some kind
// that the component can use to know that the
// value is not yet available.
}
return this.cache[id];
}
updateFromServer(response) {
fluxDispatcher.dispatch({
type: "DATA_FROM_SERVER",
payload: {id: response.id, data: response}
});
}
// this handles the "DATA_FROM_SERVER" action
handleDataFromServer(action) {
this.cache[action.payload.id] = action.payload.data;
this.emit("change"); // or whatever you do to re-render your app
}
}
Fluxor에는 API와의 비동기 통신의 예가 있습니다.
이 블로그 투고는 이에 대해 언급하고 있으며, React의 블로그에 게재되어 있습니다.
프런트엔드 소프트웨어 백엔드와의 동기화가 여전히 어려운 문제이기 때문에 이 문제는 아직 명확하게 답변되지 않은 매우 중요하고 어려운 질문입니다.
JSX 컴포넌트에서 API 요청을 해야 합니까?가게?다른 곳?
스토어에서 요청을 수행한다는 것은 2개의 스토어가 동일한 데이터를 필요로 하는 경우 2개의 동일한 요청을 발행한다는 것을 의미합니다(스토어 간의 의존관계를 도입하지 않는 한, 저는 별로 좋아하지 않습니다).
제 경우, Q 약속을 액션 페이로드로 넣는 것이 매우 편리합니다.그 이유는 다음과 같습니다.
- 액션은 시리얼화할 필요가 없습니다(이벤트 로그를 남기지 않습니다.이벤트 소스의 이벤트 재생 기능은 필요 없습니다).
- 이를 통해 다른 액션/이벤트(요구 실행/요구 완료/요구 실패)를 가질 필요가 없어지고 동시 요청을 실행할 수 있는 경우 상관 ID를 사용하여 이들 액션/이벤트를 일치시켜야 합니다.
- 여러 스토어가 스토어 간에 종속성을 도입하지 않고 동일한 요청의 완료를 리슨할 수 있습니다(그러나 캐싱 레이어를 도입하는 것이 더 나을 수 있습니다).
에이잭스는 악마다
나는 Ajax가 가까운 미래에 점점 덜 사용될 것이라고 생각한다. 왜냐하면 그것은 매우 이해하기 어렵기 때문이다.올바른 길?디바이스를 분산 시스템의 일부로서 생각하면, 이 아이디어가 어디에서 처음 떠올랐는지 알 수 없습니다(아마도 이 영감을 주는 Chris Granger 비디오에서).
생각해 보세요.이제 확장성을 위해 스토리지 엔진으로 일관된 분산 시스템을 사용합니다(CAP 정리를 능가할 수 없고 종종 가용성을 원하기 때문입니다).이들 시스템은 (컨센서스 조작을 제외하고) 서로 폴링을 통해 동기화하는 것이 아니라 CRDT 및 이벤트 로그와 같은 구조를 사용하여 분산 시스템의 모든 구성원을 최종적으로 일관되게 만듭니다(구성원은 충분한 시간이 주어지면 동일한 데이터로 수렴합니다).
이제 모바일 디바이스 또는 브라우저에 대해 생각해 보겠습니다. 네트워크 레이텐시와 네트워크 파티셔닝을 겪을 수 있는 것은 분산 시스템의 멤버뿐입니다.(즉 지하철에서 스마트폰을 사용하고 있는 경우)
네트워크 파티션과 네트워크 속도 허용 데이터베이스를 구축할 수 있다면(즉, 격리된 노드에 대한 쓰기 작업을 계속 수행할 수 있음), 이러한 개념에서 영감을 얻은 프론트 엔드 소프트웨어(모바일 또는 데스크톱)를 구축할 수 있을 것입니다.이 소프트웨어는 앱 기능을 사용할 수 없는 즉시 지원되는 오프라인 모드에서 잘 작동합니다.
프런트 엔드 애플리케이션을 구축하기 위해 데이터베이스가 어떻게 기능하고 있는지 스스로 깨달아야 한다고 생각합니다.주의할 점은 이러한 앱은 서로 데이터를 전송하기 위해 POST 및 PUT 및 GET ajax 요청을 수행하는 것이 아니라 이벤트 로그와 CRDT를 사용하여 최종적인 일관성을 보장한다는 것입니다.
그럼 프런트엔드로 하면 어떨까요?백엔드는 이미 이러한 방향으로 이동하고 있으며, Kafka와 같은 툴은 대기업에 의해 대규모로 채택되고 있습니다.이는 이벤트 소싱/CQRS/DD와도 관련이 있습니다.
Kafka 작가들의 멋진 기사를 체크하고 자신을 납득시키세요.
Ajax 요청을 실행하는 대신 서버에 명령어를 보내고 서버 이벤트 스트림을 수신하는 것부터 시작할 수 있습니다(예시를 위한 웹 소켓을 통해).
저는 Ajax의 요청에 매우 만족한 적이 없습니다.We React developers는 기능성 프로그래머인 경향이 있습니다.프런트 엔드 애플리케이션의 「진실 정보원」이라고 생각되는 로컬 데이터에 대해서는, 납득하기 어렵다고 생각합니다만, 실제의 정보원은 서버 데이타베이스에 있습니다.또, 「로컬」진실 정보원은, 수신시에 이미 낡은 것일지도 모릅니다.제대로 된 가치의 원천으로 수렴할 수 없습니다.재충전 버튼을 누르지 않으면...이건 공학적인 건가요?
그러나 몇 가지 분명한 이유로 이러한 제품을 설계하는 것은 여전히 어렵습니다.
- 모바일/브라우저 클라이언트는 리소스가 한정되어 있어 모든 데이터를 로컬에 저장할 수 없습니다(따라서 Ajax 요청 시 대량의 콘텐츠를 폴링해야 하는 경우도 있습니다).
- 클라이언트는 분산 시스템의 모든 데이터를 볼 수 없기 때문에 보안상의 이유로 수신하는 이벤트를 필터링할 필요가 있습니다.
작업 작성자 또는 스토어에서 데이터를 호출할 수 있습니다.중요한 것은 응답을 직접 처리하는 것이 아니라 오류/성공 콜백에서 액션을 작성하는 것입니다.저장소에서 직접 반응을 처리하면 설계가 더 취약해집니다.
나는 플럭소르 아약스 예제의 바이너리 뮤즈의 예를 사용해 왔다.다음은 동일한 접근방식을 사용한 매우 간단한 예입니다.
간단한 제품 스토어와 컨트롤러 뷰 컴포넌트에는 제품 스토어의 변경에 대응하는 서브 컴포넌트가 있습니다.예를 들어 product-slider, product-list 및 product-search 컴포넌트가 있습니다.
가짜 제품 클라이언트
다음은 실제 엔드포인트 반품 제품에 전화를 거는 대신 사용할 수 있는 가짜 클라이언트입니다.
var ProductClient = {
load: function(success, failure) {
setTimeout(function() {
var ITEMS = require('../data/product-data.js');
success(ITEMS);
}, 1000);
}
};
module.exports = ProductClient;
제품 스토어
여기가 프로덕트 스토어입니다.분명히 이 가게는 아주 작은 가게입니다.
var Fluxxor = require("fluxxor");
var store = Fluxxor.createStore({
initialize: function(options) {
this.productItems = [];
this.bindActions(
constants.LOAD_PRODUCTS_SUCCESS, this.onLoadSuccess,
constants.LOAD_PRODUCTS_FAIL, this.onLoadFail
);
},
onLoadSuccess: function(data) {
for(var i = 0; i < data.products.length; i++){
this.productItems.push(data.products[i]);
}
this.emit("change");
},
onLoadFail: function(error) {
console.log(error);
this.emit("change");
},
getState: function() {
return {
productItems: this.productItems
};
}
});
module.exports = store;
이제 제품 액션은 AJAX 요청을 만들고 성공 시 LOAD_PRODUCTS_SUCCES 액션을 실행하여 제품을 스토어로 반환합니다.
제품 액션
var ProductClient = require("../fake-clients/product-client");
var actions = {
loadProducts: function() {
ProductClient.load(function(products) {
this.dispatch(constants.LOAD_PRODUCTS_SUCCESS, {products: products});
}.bind(this), function(error) {
this.dispatch(constants.LOAD_PRODUCTS_FAIL, {error: error});
}.bind(this));
}
};
module.exports = actions;
전화하기this.getFlux().actions.productActions.loadProducts()
어떤 컴포넌트에서도 제품을 로딩할 수 있습니다.
은 다양하다고 할 수 .addProduct(id)
removeProduct(id)
은은패패 따따따따따
이 예는 구현하기가 조금 어렵지만, 확실히 스토어의 동기화를 100% 유지하는 데 도움이 되기를 바랍니다.
여기서 관련 질문에 답했습니다.플럭스로 중첩된 API 호출을 처리하는 방법
행동은 변화를 일으키는 것이 되어서는 안 된다.그것들은 응용 프로그램에 외부 세계의 변화를 알리는 신문과 같은 것이어야 하고, 응용 프로그램은 그 소식에 반응한다.가게 자체가 변화를 일으킵니다.행동은 그들에게 알려준다.
Flux https://stackoverflow.com/a/26581808/4258088의 크리에이터 Bill Fisher 씨
기본적으로 해야 할 일은 필요한 데이터를 행동을 통해 명시하는 것입니다.저장소가 액션에 의해 통지를 받으면 데이터를 가져올 필요가 있는지 여부를 결정해야 합니다.
저장소는 필요한 모든 데이터를 축적/가져오는 책임을 져야 합니다.단, 스토어에서 데이터를 요청하고 응답을 받은 후에는 스토어에서 응답을 직접 처리/저장하는 것이 아니라 가져온 데이터로 작업 자체를 트리거해야 합니다.
상점은 다음과 같습니다.
class DataStore {
constructor() {
this.data = [];
this.bindListeners({
handleDataNeeded: Action.DATA_NEEDED,
handleNewData: Action.NEW_DATA
});
}
handleDataNeeded(id) {
if(neededDataNotThereYet){
api.data.fetch(id, (err, res) => {
//Code
if(success){
Action.newData(payLoad);
}
}
}
}
handleNewData(data) {
//code that saves data and emit change
}
}
이에 대한 제 의견은 다음과 같습니다.http://www.thedreaming.org/2015/03/14/react-ajax/
도움이 됐으면 좋겠다.:)
언급URL : https://stackoverflow.com/questions/26632415/where-should-ajax-request-be-made-in-flux-app
'programing' 카테고리의 다른 글
적발되지 않은 불변 위반:이전 렌더링 때보다 더 많은 후크가 렌더링되었습니다. (0) | 2023.03.29 |
---|---|
com.sun.jdi 입니다.호출메서드를 호출하는 동안 예외가 발생했습니다. (0) | 2023.03.29 |
네스트된 객체에 대해 State를 설정하려면 어떻게 해야 합니까? (0) | 2023.03.29 |
D3.js: 이미지(데이터에 지정된 파일 이름 포함)를 축의 틱 값으로 사용 (0) | 2023.03.29 |
다른 인수로 같은 함수를 두 번 조롱합니다. (0) | 2023.03.29 |