casper
12.Сентябрь.2018 09:55:24
1
Всем привет, столкнулся с такой проблемой. В компонент передаю данные, считаю их и хочу вывести в 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)
Кто знает как решить проблему?
dmitry
12.Сентябрь.2018 11:50:55
2
Какие значения в консоли дает эта строка?
casper
12.Сентябрь.2018 11:53:18
3
Десятичные числа, ты думаешь надо только целые?(
dmitry
12.Сентябрь.2018 11:53:45
4
Я проверил на сайте с доками - десятичные хавает без проблем
dmitry
12.Сентябрь.2018 11:55:35
5
casper:
Десятичные числа
Десятичные на сколько? 10.888
- всмысле большая ли целая часть в десятичных?
casper
12.Сентябрь.2018 11:59:57
6
Нет, не большая. Я сейчас обернул все в Math.round(), все равно также работает((
Сейчас выдает целые числа, вот так
dmitry
12.Сентябрь.2018 12:05:28
7
Цифры правильные, следовательно работать должно.
Можешь ради интереса убрать все обертки и оставить в рендере только:
<ProgressBar active now={process} label={`${process}%`}/>
?
Может реакт что-то переоптимизирует и решает не перерендеривать. Уберем обертки чтобы избавиться от потенциального шума.
casper
12.Сентябрь.2018 12:10:47
8
Все равно, оставил в return только
<ProgressBar active now={process} label={`${process}%`}/>
casper
12.Сентябрь.2018 12:12:34
9
Даже если оставляю только
<div>{process}</div>
ничего не происходит
dmitry
12.Сентябрь.2018 12:13:40
10
casper:
<div>{process}</div>
^^^ Только хотел предложить попробовать.
Сколько физического времени проходит между началом и завершением процесса инициализции компонент? (можно включить в консоли таймстемпы чтобы увидеть даты рядом с console.log-ами)
dmitry
12.Сентябрь.2018 12:37:11
12
Попробовал изолировать компонент - и получилось работает как надо
x35njpvjro using bootstrap, react, react-bootstrap, react-dom, react-scripts
Можешь прикрутить к этому коду свою часть со стейтом?
casper
12.Сентябрь.2018 13:14:22
13
Там у меня в цикле запускается функция, которая передает в store данные, а модалка получает эти данные.
Может быть из-за того, что он не успевает перерендериться, а ему приходят другие данные. А в конце т.к ничего не приходить он спокойно рендериться?
dmitry
12.Сентябрь.2018 14:40:13
14
Если я верно интерпретирую временные промежутки между консоль логами, то времени компоненту для перерисовки предостаточно.
Может дело в том как данные попадают в стор? Хотя странно, конечно, ибо render
-то вызывается у ModalGenerating
.
Может ситуация схожа с этой проблемой - Components not re-rendering with connect() · Issue #585 · reduxjs/redux · GitHub ?
Покажи редьюсеры. Попробуем копать надо в их направлении.
casper
12.Сентябрь.2018 14:50:24
15
Вот
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 )
dmitry
12.Сентябрь.2018 18:53:30
16
Я включил работу со стейтом в мой пример https://codesandbox.io/s/2x076v9v5p все равно работает корректно. Можешь модифицировать так чтобы было больше похоже на то происходит в твоем коде?
casper
13.Сентябрь.2018 10:32:06
17
Привет, я перекинул кусок из твоего примера в свой, где он расходился. А именно
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 с таймаутом?
dmitry
13.Сентябрь.2018 11:14:25
18
Можешь показать как именно выглядит твой цикл? Может он блокирующий и браузер ничего не отрисовывает?
casper
13.Сентябрь.2018 11:30:49
19
Вот так выглядит.
//_.each - цикл из underscore js
_.each(data, function(placement , key) {
props.progressBar(key, arrayLength); // прогрессбар
if(template == 1){
//Выполняются асинхронные ajax запросы
}
if(template == 2){
//Выполняются асинхронные ajax запросы
}
});
dmitry
13.Сентябрь.2018 11:34:25
20
Не вижу ничего предосудительного в таком цикле. Единственная мысль - может запросы на самом деле синхронные.
Если они действительно асинхронные, то у меня нет хороших советов что именно делать. Мне недостаточно информации чтобы сделать выводы. Проблема локализована в том как инициализируются данные для прогрессбара - нужно играться с этим местом.