React / Redux - 为什么Promise.all在发送后继续执行?

时间:2018-02-27 03:42:35

标签: javascript reactjs ecmascript-6 redux

我有一个带有redux的React-Native项目。 我执行一些axios调用,基本上,应用程序工作正常。 但是,有一件事是不对的。 我在调度之前放了一个console.log,甚至应用程序加载并渲染一切就好了,我看到console.log在控制台中循环开启。 我不确定为什么会这样,但我读了" run to completion" Javascript中的概念,这可能是原因。尽管如此,我无法弄明白。

任何想法如何解决这个问题?非常感谢你。

UPDATE:这是在renderEtiquetas()函数中调用动作的组件。这可能是导致此循环的原因,因为它在每个重新渲染周期运行(不确定)。我尝试将调用移动到componentDidMount()但它似乎没有运行。

我是React的新手,所以我可能会做一些愚蠢的事。

component.js

class EtiquetasList extends Component {

  componentDidMount() {
    this.props.FetchEtiquetas();
  }


  renderEtiquetas() {
    if ( this.props.etiquetas.length == 0 ) {
      return <ActivityIndicator size="large" color="#00ff00" />
    } else {
      this.props.FetchGalleries( this.props.etiquetas );
      if ( this.props.galleries.length > 0 ) {
        return this.props.etiquetas.map(etiqueta =>
          <EtiquetaDetail key={etiqueta.id} etiqueta={etiqueta} galleries={ this.props.galleries } />
        );
      }
    }
  }

  render() {
    return (
      <ScrollView>
        { this.renderEtiquetas() }
      </ScrollView>
    );

  }

}

const mapStateToProps = (state) => {

  return {
    etiquetas: state.data.etiquetas,
    isMounted: state.data.isMounted,
    galleries: state.slides.entries
  };
};

export default connect(mapStateToProps, { FetchEtiquetas, FetchGalleries })(EtiquetasList);

actions.js

export function FetchGalleries( etiquetas ) {

    return function (dispatch) {
        return Promise.all(
          etiquetas.map( record =>
            axios.get('mydomain.com/?id='+record.id)
        )).then(galleries => {

          let my_data = [];
          let data_json = '';

          galleries.map( record => {
            record.data.map( subrecord => {
              // this is simplified for this example, it works as intended
              data_json = data_json + '{ title: "' + subrecord.title+'"}';
            });

            my_data.push( data_json );

          });

        console.log( my_data ); // this keeps printing in the console
        return dispatch({ type: FETCH_GALLERIES_SUCCESS, payload: my_data });

        });
    }
}

2 个答案:

答案 0 :(得分:3)

啊哈,FetchGalleries在渲染函数中运行,会导致action->render->action->render无限循环。

编辑: 如何尝试将FetchGalleriesFetchEtiquetas合并为一个操作:

export const fetchGalleries = () => {
  return function (dispatch) {
    return axios.get('/path/to/etiquetas').then(etiquetas => {
      dispatch({ type: FETCH_ETIQUETAS_SUCCESS, payload: etiquetas });
      // ... your previous promise all code
    });
  }
}

并且只需要在fetchGalleries调用此新componentDidMount

答案 1 :(得分:1)

你很近,你只需要返回或等待Promise.all,否则就不会等待了

export function FetchGalleries( etiquetas ) {

  return function (dispatch) {
    return Promise.all(....
  }

//更新:李骏骁的回答是正确的