ProgressBar react-bootstrap проблема с рендером

Всем привет, столкнулся с такой проблемой. В компонент передаю данные, считаю их и хочу вывести в ProgressBar, но он обновляется у меня только тогда, когда набегает 100%. Пробовал использовать и обычный бутстраповский ProgressBar и react-bootstrap. При этом в компоненте срабатывает componentWillUpdate (он чисто для проверки), т.е он перерендеривается.

import React, {Component} from 'react';
import { Modal, ProgressBar  } from 'react-bootstrap';
import ReactDOM from "react-dom";
import {connect} from "react-redux";

class ModalGenerating extends Component{

    constructor(props){
        super(props);
        this.state = {
            process : 0
        };
    }

    componentWillUpdate(nextProps, nextState){

        console.log('nextProps',nextProps);
        console.log('nextState',nextState);

        return true;
    }

    render(){

        var { isShow, counter, arrayLength } = this.props;

        let closeModal = () => {
            this.setState({ isShow: false });
            ReactDOM.unmountComponentAtNode(this.props.element);
        }

        var process = counter * 100 / ( arrayLength - 1);

        console.log('process', process);

        return(
                <Modal
                    id={'modalGenerating'}
                    show={isShow}
                    onHide={closeModal}
                    dialogClassName="width-50-percent"
                    restoreFocus={false}
                    enforceFocus={false}
                    autoFocus={false}
                >
                <Modal.Header closeButton>
                </Modal.Header>
                <Modal.Body>
                    <ProgressBar active now={process} label={`${process}%`}/>
                    <div className="progress progress-striped">
                        <div className="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40"
                             aria-valuemin="0" aria-valuemax="100" style= {{ width : process + '%' }}>
                            <span className="sr-only">{process}% Complete (success)</span>
                        </div>
                    </div>
                    <div>{process}</div>
                </Modal.Body>
            </Modal>
        )
    }

}

export default connect(
    state => ({
        counter : state.templates.counter,
        arrayLength : state.templates.arrayLength
    }),
    dispatch => ({
    })
)(ModalGenerating)

Кто знает как решить проблему?

Какие значения в консоли дает эта строка?

Десятичные числа, ты думаешь надо только целые?(

Я проверил на сайте с доками - десятичные хавает без проблем

Десятичные на сколько? 10.888 - всмысле большая ли целая часть в десятичных?

Нет, не большая. Я сейчас обернул все в Math.round(), все равно также работает((

Сейчас выдает целые числа, вот так

Цифры правильные, следовательно работать должно.

Можешь ради интереса убрать все обертки и оставить в рендере только:

<ProgressBar active now={process} label={`${process}%`}/>

?

Может реакт что-то переоптимизирует и решает не перерендеривать. Уберем обертки чтобы избавиться от потенциального шума.

Все равно, оставил в return только

   <ProgressBar active now={process} label={`${process}%`}/>

Даже если оставляю только

<div>{process}</div>

ничего не происходит

^^^ Только хотел предложить попробовать.

Сколько физического времени проходит между началом и завершением процесса инициализции компонент? (можно включить в консоли таймстемпы чтобы увидеть даты рядом с console.log-ами)

Вот, общее снизу

Попробовал изолировать компонент - и получилось работает как надо

Можешь прикрутить к этому коду свою часть со стейтом?

Там у меня в цикле запускается функция, которая передает в store данные, а модалка получает эти данные.

Может быть из-за того, что он не успевает перерендериться, а ему приходят другие данные. А в конце т.к ничего не приходить он спокойно рендериться?

Если я верно интерпретирую временные промежутки между консоль логами, то времени компоненту для перерисовки предостаточно.

Может дело в том как данные попадают в стор? Хотя странно, конечно, ибо render-то вызывается у ModalGenerating.

Может ситуация схожа с этой проблемой - https://github.com/reduxjs/redux/issues/585?
Покажи редьюсеры. Попробуем копать надо в их направлении.

Вот

import { combineReducers } from 'redux'

export default combineReducers({
    templates(state = '', action) {
        switch(action.type) {
            case 'ADD_COUNTER_MODAL_GENERATING':
                const data = action.data;
                return Object.assign({}, state, { counter : data.counter, arrayLength : data.arrayLength});
            case 'ADD_PARAM':
                return Object.assign({}, state, { param : action.param });
        }
        return state;
    }
})

В цикле выполняется ADD_COUNTER_MODAL_GENERATING и передается длина массива ( arrayLength ) и сколько уже выполнилось ( counter )

Я включил работу со стейтом в мой пример https://codesandbox.io/s/2x076v9v5p все равно работает корректно. Можешь модифицировать так чтобы было больше похоже на то происходит в твоем коде?

Привет, я перекинул кусок из твоего примера в свой, где он расходился. А именно

const arrl = 10;
let counter = 1;
const iid = setInterval(() => {
  if (counter === arrl) {
    clearInterval(iid);
  }
  if (Math.random() > 0.5) {
    counter += 1;
    store.dispatch({
      type: "ADD_COUNTER_MODAL_GENERATING",
      data: {
        counter: counter,
        arrayLength: arrl
      }
    });
  }
}, 100);

И у меня все заработало. Видимо дело все же в цикле. Есть варианты как лучше сделать в данном случае? Promise с таймаутом?

Можешь показать как именно выглядит твой цикл? Может он блокирующий и браузер ничего не отрисовывает?

Вот так выглядит.

//_.each - цикл из underscore js

_.each(data, function(placement , key) {

          
            props.progressBar(key, arrayLength); // прогрессбар

            if(template == 1){
               //Выполняются асинхронные ajax запросы 
            }

            if(template == 2){
                //Выполняются асинхронные ajax запросы 
            }

});

Не вижу ничего предосудительного в таком цикле. Единственная мысль - может запросы на самом деле синхронные.

Если они действительно асинхронные, то у меня нет хороших советов что именно делать. Мне недостаточно информации чтобы сделать выводы. Проблема локализована в том как инициализируются данные для прогрессбара - нужно играться с этим местом.