我有一个触发许多更新的应用程序,我想了解有关正确更新该应用程序的最佳方法的更多信息。
在我的应用中,我有5个插槽可以装满书籍(可以通过拖放进行管理)。应用启动时,将为用户填充已填充的书,并将其存储在状态中。
问题:更新一本书时,例如,如果我切换清单中的2本书的位置,我必须做一些操作,说“这本书现在属于这里,另一本书现在属于这里,切换!” >
我觉得我正在做一些乏味的操作,因为如果我只是从API调用中返回全部数据(在更新后获取),然后调用“加载”功能(就像我启动应用程序时一样),不必处理操作更新。
此外,如果我正确加载但未正确更新(例如,如果我错过一本书的位置),它可能会产生错误
我在功能更新中看到的好处是,我只更新了我需要的两本书,而不是一次又一次地重新加载它们。
哪种方法更好?我应该摆脱那些更新功能,而只是完全重新加载数据吗?我认为可能还会有一些图书馆将其缓存,以便仅重新呈现修改后的书
谢谢
答案 0 :(得分:1)
没有代码很难完全理解问题,但是从服务器获取数据有两个优点。
因此,我通常选择获取服务器上的数据。
基于用户交互来获取数据的一个问题是,获取是异步的,因此可能发生以下情况:
用户执行操作A,针对A的请求,用户执行操作B,针对B的请求,B请求解析,并且将UI设置为请求B的结果,针对A的请求解析,并将UI设置为A的结果。
因此,用户执行操作的顺序并不能保证解决请求的顺序。
要解决此问题,您可以使用仅在上次请求时才进行解析的助手,在上面的示例中,当一个请求解析出UI时,无需设置任何内容,因为它已被另一个请求替换。>
在下面的示例中,您可以键入搜索值,当该值是1个字符长时,将需要2秒钟才能解决,因此当您键入ab
时,ab
请求将在{{ 1}}请求。但是由于发出请求的函数在a
解析时被last
帮助程序包装,因此将被拒绝,因为它已被较新的请求a
取代。
ab
//constant to reject with when request is replaced with a
// more recent request
const REPLACED = {
message: 'replaced by more recent request',
};
//helper to resolve only last requested promise
const last = (fn) => {
const check = {};
return (...args) => {
const current = {};
check.current = current;
return Promise.resolve()
.then(() => fn(...args))
.then((result) => {
//see if current request is last request
if (check.current === current) {
return result;
}
//was not last request so reject
return Promise.reject(REPLACED);
});
};
};
const later = (howLong, value) =>
new Promise((resolve) =>
setTimeout(() => resolve(value), howLong)
);
const request = (value) =>
later(value.length === 1 ? 2000 : 10, value).then(
(result) => {
console.log('request resolved:', result);
return result;
}
);
const lastRequest = last(request);
const App = () => {
const [search, setSearch] = React.useState('');
const [result, setResult] = React.useState('');
React.useEffect(() => {
//if you use request instead of lastRequest here
// you see it will break, UI is updated as requests
// resolve without checking if it was the last request
lastRequest(search)
.then((result) => setResult(`result:${result}`))
.catch((err) => {
console.log(
'rejected with:',
err,
'for search:',
search
);
if (err !== REPLACED) {
//if the reject reason is not caused because request was
// replaced by a newer then reject this promise
return Promise.reject(err);
}
});
}, [search]);
return (
<div>
<label>
search
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
></input>
</label>
<div>{result}</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));