gpt4 book ai didi

ajax - [React]将异步数据获取到组件中的不同方式

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

我对 React 世界有点陌生,最近当我开始在组件内编写 Ajax 内容时,我感到很困惑。

据我所知,有两种将异步数据渲染到组件中的方法,如下所示:

第一种方法:

class MyComponent extends React.Component
{
render() {
this.props.userList.map((userInfo) => (<span>{userInfo.name}</span>));
// proceed to render userList
}
}

//userAjaxSelect is a customized selector based on the Reselect lib
//ajax operation happens here!!
const mapStateToProps = (state, props) => {
return {
userList:userAjaxSelect(state, props)
}
}

const mapDispatchToProps = null;// mapDispatchToProps is omitted here

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

第二种方式:

export default class MyComponent extends React.Component
{

componentDidMount() {
//FetchUserList is a redux ActionCreator and omitted here
//it dispatches redux action
//To get ajax response and sync to local UI state.
this.setState({userList: FetchUserList(this.props.groupId)})
}

componentWillReceiveProps(nextProps) {
if(nextProps != this.props)
//FetchUserList is a redux ActionCreator and omitted here
//it dispatches redux action
//To get ajax response and sync to local UI state.
this.setState({userList: FetchUserList(nextProps.groupId)})
}

render() {
this.state.userList.map((userInfo) => (<span>{userInfo.name}</span>);
// proceed to render userList
}
}

从我的角度来看,

第一个解决方案:

ajax操作封装在Reselect lib中使用的Selector中,我认为它非常干净并且可以提高组件性能(通过缓存)

第二个解决方案:

这是一件坏事吗?因为很多时候有几篇文章警告我不鼓励使用 componentWillReceiveProps 设置状态(反模式)?而且它的实现方式也比较冗长

<小时/>

哪一个是最佳实践或任何其他更好的替代方案?当涉及到加载和刷新 Ajax 数据时

最佳答案

老实说,我从未使用过您展示的任何方法。根据文档,您可能希望在 componentDidMount 中进行任何 AJAX 请求,并避免在 componentWillReceiveProps 中执行 AJAX。

其背后的原因是,即使没有必要的数据,您的组件也应该被安装,您不想阻塞 View (例如,如果您使用 componentWillMount 就会发生这种情况),如果请求时间太长。我经常看到的模式如下:

export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { isFetching: false, userList: [] };
}

componentDidMount() {
this.setState({ isFetching: true });
// In this case FetchUserList is just a simple AJAX call
// not an action
FetchUserList(this.props.groupId)
.then((data) => {
this.setState({ userList: data, isFetching: false });
});
}

render() {
this.state.userList.map((userInfo) => (<span>{userInfo.name}</span>);
}
}

这没有考虑错误处理,但我希望您能明白(您可以使用 .catch )。如果您的状态已填充,您甚至可以阻止发送请求,或者如果数据已经存在,则避免设置状态等等...

另一方面,如果您使用的是 redux,有许多中间件可以帮助您实现这一点,例如 redux-thunk,或者我确实创建了一个中间件,也称为 >redux-slim-async 减少了样板文件,并且结合了 redux 文档中显示的内容和一些附加功能。归根结底,请使用您感到满意且对您的代码库更有意义的内容。

<小时/>

使用redux的另一种方法可能是在componentDidMount内触发异步操作,然后您的组件监听状态的一部分(使用 >mapStateToProps)它感兴趣,并且使用 componentWillReceiveProps 您可以根据从管理器收到的新 props 更新组件的内部状态。你所展示的是一种我不推荐的混合体。

export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { userList: [] };
}

componentDidMount() {
// In this case FetchUserList is an Action
FetchUserList(this.props.groupId)
}

componentWillReceiveProps(nextProps) {
if(nextProps != this.props) {
this.setState({ userList: nextProps.propFromStateManager });
}
}

render() {
this.state.userList.map((userInfo) => (<span>{userInfo.name}</span>);
}
}

请记住,仅当您需要根据某些 props 更改来更新组件的内部状态时,才应使用 componentWillReceiveProps。我会看到 reselect 派上用场的情况是,当您无论如何都想发送 fetch 请求更新状态,然后 reselect 将检查如果状态完全相同,在这种情况下它可能会阻止重新渲染。否则我不会触发来自选择器的 ajax 请求。如果我要跳入您的代码,我永远不会期望在选择器中找到异步调用,这不是它们的用途。

如果您需要澄清,请告诉我,我会更新答案。

关于ajax - [React]将异步数据获取到组件中的不同方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48325389/

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