gpt4 book ai didi

reactjs - Flux中HTTP请求应该从哪里发起?

转载 作者:行者123 更新时间:2023-12-03 13:51:57 25 4
gpt4 key购买 nike

有一个plentydiscussion关于如何在 Flux 中与外部服务通信。

很明显,基本工作流程是触发 HTTP 请求,最终将根据响应分派(dispatch)成功或失败的操作。您还可以选择在发出请求之前分派(dispatch)“进行中”操作。

但是如果请求的参数取决于商店的状态怎么办?似乎没有人提到它。

因此,本质上,根据用户与 View 的交互,调度一个 ACTION。 Store 拥有关于如何从当前 state0 转换到给定 ACTION 的下一个 state1 的逻辑。需要来自 state1 的数据才能正确形成新的 HTTP 请求。

例如,用户在页面上选择了新的过滤器,商店决定也重置分页。这应该会导致一个新的 HTTP 请求,其中包含(新过滤器值,第一页),而不是(新过滤器值,来自 state0 的当前页面)。

View 无法使 HTTP 调用本身与用户交互正确,因为它必须复制存储的逻辑才能转换到下一个状态。

View 无法在其存储的 onChange 处理程序中进行 HTTP 调用,因为此时它不再知道状态更改的来源。

这看起来是一个可行的选择,可以让商店在转换到下一个状态后在操作处理程序中触发 HTTP 请求。但这将使此操作隐式启动 HTTP 调用,从而无法获得用于调试的已调度操作的可重播日志。

Flux 中 HTTP 请求应该从哪里发起?

最佳答案

让我们从底部开始:

It looks like a viable option to make store fire the HTTP request in the action handler, after it transitioned to the next state. But this will make this action implicitly initiating HTTP call, which disables neat possibility to have a replayable log of dispatched actions for debugging.

如果您处于调试/重播模式,可以通过不发起 HTTP 请求来缓解此问题。只要您在 HTTP 请求处理程序中执行的唯一操作是触发操作(例如 SUCCESSFAILURE 操作),此方法就非常有效。您可以使用简单的全局 bool 值 (if (!debug) { httpReq(...) }) 来实现此目的,但您也可以使该模式更加正式。

Event Sourcing说法,你使用 Gateways出于此类目的。在正常操作中,网关会发出 HTTP 请求,而在调试过程中,您会关闭网关(因此它不会发出任何 HTTP 请求)。

也就是说,我认为这个问题实际上可以通过重新考虑 HTTP 请求的发出位置来解决。

So essentially, based on user interaction with the view, an ACTION is dispatched. Store owns logic on how to transition from current state0 to the next state1 given ACTION. Data from state1 is needed to properly form new HTTP request.

在您问题的第二个链接中( Where should ajax request be made in Flux app? ), I recommend在操作创建器中进行写入,但在商店中进行读取。如果您将该模式推断到您的用例中,您可能最终会得到类似这样的结果(为了清楚起见,使用伪代码和长变量名称):

class DataTable extends React.Component {
render() {
// Assuming that the store for the data table contains two sets of data:
// one for the filter selection and one for the pagination.
// I'll assume they're passed as props here; this also assumes that
// this component is somehow re-rendered when the store changes.
var filter = this.props.filter;
var start = this.props.start;
var end = this.props.end;

var data = this.props.dataTableStore.getDataForPageAndFilter(
start, end, filter
);

// the store will either give us the LOADING_TOKEN,
// which indicates that the data is still loading,
// or it will give us the loaded data
if (data === DataTableStore.LOADING_TOKEN) {
return this.renderLoading();
} else {
return this.renderData(data);
}
}
}

class DataTableStore {
constructor() {
this.cache = {};
this.filter = null;
this.start = 0;
this.end = 10;
}

getDataForPageAndFilter(start, end, filter) {
var url = HttpApiGateway.urlForPageAndFilter(start, end, filter);

// in a better implementation, the HttpApiGateway
// might do the caching automatically, rather than
// making the store keep the cache
if (!this.cache[url]) {
this.cache[url] = DataTableStore.LOADING_TOKEN;

HttpApiGateway.query(url)
.then((response) => {
// success
var payload = {
url: url,
data: response.body
};
dispatch(DATA_FETCH_SUCCESS, payload);
}, (error) => {
// error
dispatch(DATA_FETCH_FAIL, { ... });
});
}

return this.cache[url];
}

handleChangeFilterAction(action) {
this.filter = action.payload.filter;
// the store also decides to reset pagination
this.start = 0;
this.end = 10;
this.emit("change");
}

handleDataFetchSuccessAction(action) {
this.cache[action.payload.url] = data;
this.emit("change");
}

handleDataFetchFailAction(action) {
// ...
}
}

DataTableStore.LOADING_TOKEN = "LOADING"; // some unique value; Symbols work well

您可以看到,存储负责决定如何更新分页和过滤器变量,但不负责决定何时应发出 HTTP 请求。相反, View 只是请求一些数据,如果存储在缓存中没有这些数据,它将然后发出 HTTP 请求。

这还允许 View 将任何其他本地状态传递到 getter 中(以防 HTTP 请求也依赖于本地状态)。

关于reactjs - Flux中HTTP请求应该从哪里发起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29875812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com