gpt4 book ai didi

listview - 使用 API 和 AsyncStorage 数据构建 ListView

转载 作者:行者123 更新时间:2023-12-03 14:15:17 25 4
gpt4 key购买 nike

为了构建我的 React Native ListView,我需要从两个地方提取数据:网络 APi 和 AsyncStorage(如 AppCache)。来自 AsyncStorage 的数据可能存在,也可能不存在,但它需要以任何方式返回一些内容(例如“未找到”)

这是当前版本的要点,除了检索 cachedOn 日期 ( Line 47 ) 之外,该版本都有效 https://gist.github.com/geirman/1901d4b1bfad42ec6d65#file-aircraftlist-js-L47 ,我相信这就是秘诀所在。

我认为这可能是任何 ReactJS 开发人员都可以回答的问题,尽管该示例是 React Native 特定的。

Screenshot

最佳答案

问题看起来相当复杂,因为存在多个级别的异步性:获取数据、读/写缓存以及呈现列表行。在这种情况下,将问题分解为更小的组件通常会有所帮助。

我无法轻松运行示例代码,因此我使用了一个简化的示例。

首先,让我们将缓存包装到一个简洁的界面中,这样我们在使用它时就不需要考虑 AsyncStorage 语义:

const aircraftCache = {
// returns promise of cached aircraft, or null if not found
getAircraft(aircraftId) {
return AsyncStorage.getItem(aircraftId).then(data => (
data ? JSON.parse(data) : null
));
},

// caches given aircraft object with a fresh cachedOn date
// and returns a promise of the cached aircraft
setAircraft(aircraftId, aircraft) {
const cached = {...aircraft, cachedOn: new Date()};
return AsyncStorage.setItem(aircraftId, JSON.stringify(cached)).then(() => cached);
},

// clears given aircraft from cache and return Promise<null>
clearAircraft(aircraftId) {
return AsyncStorage.removeItem(aircraftId).then(() => null);
}
}

然后,让我们将 AircraftList 的职责限制为仅显示数据列表、加载指示器等,并将行渲染提取到单独的组件:

class AircraftList extends Component {
static propTypes = {
aircraft_list: PropTypes.arrayOf(PropTypes.shape({
reg_number: PropTypes.string,
ti_count: PropTypes.number
}))
}

constructor(props) {
super(props);
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
dataSource: this.ds.cloneWithRows(this.props.aircraft_list),
isLoading: false,
showingCache: false
};
}

aircraftLoaded(aircraft) {
this.setState({isLoading: false});
this.props.navigator.push({
title: 'TI Lookup',
component: TrackedItemIndex,
passProps: {aircraft_object: aircraft}
});
}

renderRow(aircraft) {
return (
<AircraftRow
reg_number={aircraft.reg_number}
ti_count={aircraft.ti_count}
loading={() => this.setState({isLoading: true})}
loaded={this.aircraftLoaded.bind(this)}
/>
);
}

render() {
// simplified view
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
/>
);
}
}

然后可以将各个行渲染、获取和缓存操作封装到 AircraftRow 组件中:

class AircraftRow extends Component {
static propTypes = {
reg_number: PropTypes.string,
ti_count: PropTypes.number,
loading: PropTypes.func,
loaded: PropTypes.func
}

state = { cachedOn: null };

constructor(props) {
super(props);

this.loadDetails = this.loadDetails.bind(this);
this.clearDetails = this.clearDetails.bind(this);
this.setCachedOn = this.setCachedOn.bind(this);
}

componentWillMount() {
// when component is loaded, look up the cached details and
// set the cachedOn timestamp into state
aircraftCache.getAircraft(this.props.reg_number).then(this.setCachedOn);
}

loadDetails() {
const id = this.props.reg_number;
// notify parent that loading has started
if (this.props.loading) {
this.props.loading(id);
}

// fetch and cache the data
this.fetchDetails(id)
.then((aircraft) => {
// notify parent that loading has finished
if (this.props.loaded) {
this.props.loaded(aircraft);
}
})
.catch((e) => {
console.error(e);
});
}

fetchDetails(id) {
// get details from the api, and fall back to the cached copy
return Api.getTrackedItems(id)
.then(aircraft => aircraftCache.setAircraft(id, aircraft))
.then(this.setCachedOn)
.catch(() => aircraftCache.getAircraft(id));
}

clearDetails() {
// clear item from cache and update local state with null aircraft
const id = this.props.reg_number;
aircraftCache.clearAircraft(id).then(this.setCachedOn);
}

setCachedOn(aircraft) {
// update local state (aircraft can be null)
this.setState({ cachedOn: aircraft ? aircraft.cachedOn.toString() : null })
return aircraft;
}

render() {
// simplified view
return (
<View>
<Text>{this.props.reg_number}</Text>
<Text>{this.props.ti_count}</Text>
<Text>{this.state.cachedOn}</Text>
<Text onPress={this.loadDetails}>Load details</Text>
<Text onPress={this.clearDetails}>Clear details</Text>
</View>
)
}
}

就我的钱而言,这个观点仍然太过分了。我建议研究 Redux 或 MobX 等状态管理库来进一步简化代码 - 当然,尽管它们也有自己的复杂性。

关于listview - 使用 API 和 AsyncStorage 数据构建 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33424397/

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