Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ajax [React]将异步数据提取到组件中的不同方法_Ajax_Reactjs_Redux_React Redux - Fatal编程技术网

Ajax [React]将异步数据提取到组件中的不同方法

Ajax [React]将异步数据提取到组件中的不同方法,ajax,reactjs,redux,react-redux,Ajax,Reactjs,Redux,React Redux,我对React world有点陌生,最近当我开始在组件中编写Ajax时,我感到困惑 就我所见,以下是将异步数据呈现到组件中的两种方法: export default class MyComponent extends React.Component { constructor(props) { super(props); this.state = { isFetching: false, userList: [] }; } componentDidMount() {

我对React world有点陌生,最近当我开始在组件中编写Ajax时,我感到困惑

就我所见,以下是将异步数据呈现到组件中的两种方法:

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>);
  }
}
第一条路:

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)
类MyComponent扩展了React.Component { render(){ this.props.userList.map((userInfo)=>({userInfo.name})); //继续呈现用户列表 } } //userAjaxSelect是一个基于重新选择库的自定义选择器 //ajax操作发生在这里!! 常量mapStateToProps=(状态、道具)=>{ 返回{ userList:userAjaxSelect(状态、道具) } } 常量mapDispatchToProps=null;//此处省略mapDispatchToProps 导出默认连接(MapStateTrops、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
    }
}
导出默认类MyComponent扩展React.Component
{
componentDidMount(){
//FetchUserList是redux ActionCreator,此处省略
//它发送redux操作
//获取ajax响应并同步到本地UI状态。
this.setState({userList:FetchUserList(this.props.groupId)})
}  
组件将接收道具(下一步){
if(nextrops!=this.props)
//FetchUserList是redux ActionCreator,此处省略
//它发送redux操作
//获取ajax响应并同步到本地UI状态。
this.setState({userList:FetchUserList(nextrops.groupId)})
}
render(){
this.state.userList.map((userInfo)=>({userInfo.name});
//继续呈现用户列表
}
}
在我看来,

第一种解决方案:

ajax操作被封装在一个选择器中,该选择器用于重新选择库中,我认为它非常干净,可以提高组件性能(通过缓存)

第二种解决方案:

这是一个糟糕的方法吗?因为有几篇文章多次警告我,不鼓励组件WillReceiveProps设置状态(反模式),而且它的实现方式相对冗长



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

老实说,我从来没有使用过您展示的任何方法。根据文档,您可能希望在
组件中有任何Ajax请求,并避免在
组件中使用Ajax

其背后的原因是,即使在没有必要数据的情况下也应该装入组件,如果请求时间过长,您不希望阻止视图(例如,如果使用
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>);
  }
}
请记住,
component willreceiveprops
仅当您需要根据一些
props
更改更新组件的内部状态时才应使用。我将看到
reselect
派上用场的场景是,您希望发送
fetch
请求更新状态,然后
重新选择
将为您检查状态是否完全相同,在这种情况下,它可能会阻止重新渲染。否则,我不会从选择器触发ajax请求。如果我跳入您的代码,我将永远不会期望在选择器中触发异步调用,这不是它们的用途


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

我知道有一些中间件,如React thunk、React saga等。但是,中间件在调度和操作级别发挥作用,这与我无关。事实上,我的项目决定使用重新选择库来加快redux,因此我想知道将ajax置于n选择器(在MapStateTops中使用)当我们需要将react-redux与Reselect集成时?我更新了答案,如果您需要发出相同的请求,即使您已经拥有数据,Reselect也是有意义的,在这种情况下,Reselect将利用备忘并避免触发重新渲染。但是,如果我已经拥有数据,我将首先避免发送请求。根据文档,Recelect接受许多参数(例如切片状态、组件和ownProps)如果其中任何一个发生变异,选择器的结果将被重新计算并同步到mapStateToProps,我认为这与您的解决方案的目的完全相同,您的解决方案更新componentWillReceiveProps中的UI状态以响应任何新的props。更重要的是,更新componentWillReceiveProps中的组件状态看起来更像动词ose和冗余。所有这些可能都很简单,可能没有意义,如果我错了,请纠正我,谢谢!!使用mapStateToProps,this.props(用于渲染中的输出)可以自动更新以响应任何新的道具和感兴趣状态的新变化,那么为什么我们在componentWillReceiveProps中这样做,同时拥有更多代码?请分享您的观点,谢谢!谢谢!