React Router, Redux and async API call



当用户点击链接时,React Router 将显示一个组件。此组件将显示的数据来自终结点,因此我想知道最佳做法是什么。

我创建了一个名为fetchData的函数,它使用fetch在端点中执行 GET,然后返回一个承诺。一旦这个承诺得到解决,我想调度一个 Redux 操作来更新状态。

我设法用redux-thunk做到这一点,但我想在不添加更多库的情况下实现这一点。

我正在尝试遵循"容器/表示"的想法,并且我在 React 中使用了无状态功能组件。

在一般概述中,这就是我正在做的事情:

index.js

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

app.js

const App = () => (
<div>
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path="/" component={Main} />
<Route exact path="/data-list" component={DataListContainer} />
</Switch>
</div>
</BrowserRouter>
</div>
)

dataListContainer.js

const mapStateToProps = (state) => {
return { data: state.data }
}
const mapDispatchToProps = (dispatch) => {
return { }
}
const DataListContainer = connect(
mapStateToProps,
mapDispatchToProps
)(DataList)

dataList.js

const DataList = (props) => {
const rows = props.data.map(data => {
return <Data data={data} />
})
return (
<div>
{rows}
</div>
)
}

Data组件仅显示数据。我想知道我应该在哪里添加对函数fetchData的调用,以及我应该在哪里解决返回的承诺。我想在解决承诺后我需要调度一个操作,但不确定在哪里是执行此操作的最佳位置。

另一个问题是:我只想获取一次数据,我的意思是,只有当用户单击/data-list链接时。如果它回到主页,然后再次转到data-list,我不想再次调用端点。React Route 实现中是否隐藏了任何调用一次功能?

dataListContainer.js更改为有状态的 React 组件,这没关系,因为它是容器! 不要把代码当成确切的,它只是为了给出一个想法。

import { fetchData, DataList, store } '......'
class DataListContainer extends React.Component {
componentDidMount() {
if (!this.props.data) {
store.dispatch(fetchData())
}
}
render() {
return (<DataList data={this.props.data}/>);
}
}
const mapStateToProps = (state) => {
return { data: state.data }
}
export default connect(
mapStateToProps
)(DataListContainer)

我认为这在路线和视图中是不可能的。当您使用 React 路由器切换页面时,组件会卸载。组件的所有数据也被清除。(相信我,这是你想要的。否则,您可能会遇到一些让浏览器崩溃的内存问题(。此外,您的视图只负责显示内容,而不应对其接收的数据执行操作。

看看您的商店中的一些实现。例如,将从 API 接收的数据存储在存储对象中。下次有人在存储中调用fetchData函数时,请提供存储的数据,而不是发出新请求。存储永远不会卸载,因此它可以将数据保存在内存中。请记住,仅当重新加载整个页面时,用户才会收到新数据。所以"硬刷新",但可能有用。

您可以做的另一件事是问问自己为什么不想多次调用该端点?数据集是否为大而无法接收?在这种情况下,请使用分页并将其分成几部分。

最新更新