如何在mapStateToProps中转换异步数据?

时间:2019-03-30 22:32:33

标签: reactjs redux react-redux google-cloud-firestore react-redux-firebase

  • 我正在使用firestoreConnect()将我的数据从firestore与redux同步。

  • 我正在通过state.firestore.ordered从firestore返回一系列员工对象

  • 员工的形像是这样:

    {
      id: 'XtVe567...',
      name: {
        first: 'John',
        last: 'Doe'
      }
    }
    
  • 在mapStateToProps中,我需要先转换此数据的形状,然后再将其返回并通过props传递到组件中。

    function mapStateToProps(state) {
    
      const schedules = state.firestore.ordered.employees
        .map(employee => ({
          id: employee.id,
          name: {
            first: employee.name.first,
            last: employee.name.last
          },
          schedule: [null, null, null, null, null, null, null]
        }));
    
      const rota = {
       id: null,
       date: moment(),
       notes: null,
       events: [null, null, null, null, null, null, null],
       published: null,
       body: schedules
      };
    
      return {rota}
    }
    
  • 这将导致:TypeError:无法读取未定义的属性“ map”

  • 我知道这是因为获取数据是异步的,并且是在我映射到state.firestore.ordered.employees员工的时间点的employee属性=== undefined,这是不可迭代的

所以,我的问题是如何用异步数据进行这种数据转换?有没有办法解决在映射之前如何暂停mapStateToProps的执行并等待数据返回的情况?

如果对此问题无法理解,我们表示非常感谢,这是我第一次发帖。

2 个答案:

答案 0 :(得分:0)

您的组件应对基础数据中的更改有反应。因此,您可以渲染如下内容:

getSchedules(emps) {
 return emps.map(employee => <SomeEmployeeRenderingComponent emp={employee} /> );
}
render() {
  return (
   <div>{this.getSchedules(this.props.employees).bind(this)}</div>
  )
}

和mapstatetoprops变为:

function mapStateToProps(state) {

  const rota = {
   id: null,
   date: moment(),
   notes: null,
   events: [null, null, null, null, null, null, null],
   published: null,
   employees: state.firestore.ordered.employees
  };

  return rota
}

答案 1 :(得分:0)

要使其快速生效,您可以执行以下操作:

function mapStateToProps(state) {

    const employees = state.firestore.ordered.employees;

    const schedules = employees
        ? employees.map(employee => ({
            id: employee.id,
            name: {
                first: employee.name.first,
                last: employee.name.last
            },
            schedule: [null, null, null, null, null, null, null]
        }))
        : undefined;

    const rota = {
        id: null,
        date: moment(),
        notes: null,
        events: [null, null, null, null, null, null, null],
        published: null,
        body: schedules
    };

    return { rota }
}

然后,在您的组件中,可以检查rota对象的schedules属性,如果仍未定义,请渲染一些内容以指示尚未加载数据。

不过,将如此复杂的逻辑放入mapStateToProps中对我来说是一种反模式。您可以使用选择器模式来使代码更有条理。