Комментарии 44
</b>
или так надо?)Начать с React и Bootstrap за 2 дняВот за это большое спасибо — почитаем!
Программисту для удобства разработки. Пользователю для удобства работы. Пользователи в отличие от программистов устроены так, что им важно, чтобы было красиво и приятно глазу и они не задумываются о производительности. Например, я часио наблюдаю, как у людей пользователей одновременно запущено более 10 приложений и открыто более 100 сайтов. Хотя в целях производительности надо было сократить их в идеале до 1, или хотя бы до 3-4.
Не отрицаю, что приведённый код можно (а для высоконагруженных приложений) нужно оптимизировать — про оптимизацию есть куча статей. Да то же кэширование может помочь. Статья не про это. А про то, как быстро узнать, что это за технология такая React, и можно ли сделать красиво с помощью Bootstrap?
Предлагаю решать проблемы по мере их поступления. У меня была задача за пару дней изучить React и сделать на его базе красивое Web-прмложение. В постановке задачи
В постановке задачи не было про производительность.
Если потребуется оптимизировать производительность — это уже отдельная задача. Возможно в этой задаче откажемся от Bootstrap, а может даже и от React. Может вообще о кажемся от сайта и будем делать нативное мобильное приложение с кусками кода на ассемблере)))
Зачем вам js-часть бутстрапа? Она же будет конфликтовать с React! При желании, конечно же, их можно подружить — но это требует куда более вдувчивого подхода к программированию чем тут продемонстрирован.
Ну вот, например, решили вы сделать через бутстрап Collapse. И пишете:
<>
<a className="btn btn-primary" data-toggle="collapse" href="#collapseExample" >Show/Hide</a>
<div className="collapse" id="collapseExample">
{this.props.text}
</div>
</>
Но такой компонент может при любом рендере внезапно свернуться, причем в разных версиях React это будет случаться при разных условиях. Кроме того, использование id в компонентах на React само по себе выглядит не очень.
Спасибо за уточнение. Как лучше переписать такой код?
Если анимации необязательны — то вот так:
<>
<a className="btn btn-primary" onClick={this.toggle}>Show/Hide</a>
<div className={this.state.show ? 'collapse show' : 'collapse'}>
{this.props.text}
</div>
</>
Если анимации нужны — то нужно либо искать готовое решение именно для React, либо начать с чего-то похожего на вот этот код (и быть готовым фиксить его баги):
class Collapse extends React.PureComponent {
render() {
return <div>{this.props.children}</div>
}
componentDidMount() {
const $this = $(ReactDOM.findDOMNode(this));
$this.css({ collapse: true, show: this.props.visible });
}
componentDidUpdate(prevProps) {
const $this = $(ReactDOM.findDOMNode(this));
if (this.props.visible && !prevProps.visible)
$this.collapse('show');
else if (!this.props.visible && prevProps.visible)
$this.collapse('hide');
}
componentWillUnmount() {
const $this = $(ReactDOM.findDOMNode(this));
$this.collapse('dispose');
}
}
// ...
<>
<a className="btn btn-primary" onClick={this.toggle}>Show/Hide</a>
<Collapse visible={this.state.visible}>
{this.props.text}
</Collapse>
</>
Точнее не скажу, потому что я React за пределами песочницы ни разу не использовал.
Кстати, именно из-за сложности последнего решения я и говорю, что js-часть бутстрапа начинающим лучше совместно с React не использовать: нужно понимать что этот код вообще делает, и быть готовым написать аналогичную обертку для любого бутстрап-компонента.
А по поводу jQuery пока в официальной документации обнаружил, что jQuery нужен только для JS-части Bootstrap. Сейчас думаю, как выпилить JS из Bootstrap и оставить только CSS от Bootstrap.
> this.resetTimer = this.resetTimer.bind(this);
Чтобы таким не заниматься, можно определять методы как стрелочные функции
class MyComponent extends PureComponent {
state = {
stopped: false,
};
stopTimer = () => this.setState({ stopped: true });
render() {
return (
<button onClick={this.stopTimer}>Астанавитесь!</button>
);
}
}
> для этого добавим установку document.title в метод render():
Какой ужас :)
Здесь лучше подойдёт componentDidUpdate, потому что рендер может вызываться бесчисленное количество раз в зависимости от различных условий и всё, что он должен делать — возвращать новый VDom, за счёт чего «лишний» рендер будет менее дорогим.
«В Facebook React используется в тысячах компонентов, но не было обнаружено каких-либо ситуаций, где разработчики рекомендовали бы создавать иерархии наследования компонентов.»
2.Перенёс установку заголовка в componentDidUpdate()
Нашел у вас в коде вот такую строчку:
this.setState({value: this.state.value + 1})
Здесь вы неявно предполагаете, что между вызовами setState
состояние успеет обновиться.
Так делать опасно: если на странице будет происходить что-нибудь "тяжелое", то ваш таймер начнет пропускать секунды. Казалось бы, это маловероятно, целая секунда же в периоде… Вот только тот сайт, где вы это читаете, умудряется тормозить на страницах с кучей комментариев даже без скриптов, на чистом css.
Рекомендуемый документацией React вариант выглядит вот так:
this.setState(state => ({ value: state.value+1 }));
Не стоит учить «плохому»
Для начала нам нужен менеджер пакетов. Я выбрал npm, а он есть в Node.jsНа самом деле для запуска Вам нужен Node.js, а без менеджера пакетов даже можно обойтись. Но судя по статье — нода, это просто что-то, где есть npm.
this – текущий классthis не текущий класс, а контекст. В Вашем случае — экземпляр класса.
Далее стандартная обработка конструктора родительского класса super(props)Конструктор не обрабатывается, а вызывается.
Ну и по коду.
const INTERVAL = 100;
На самом деле это не интервал, интервал в Вашем случае — 1000/INTERVAL (в описании Вы и сами пишете, что это частота).this.stopTimer = this.stopTimer.bind(this);
В комментариях уже упоминались стрелочные функции и proposal class properties.this.setState({value: this.state.value + 1})
Также в комментариях уже упоминалось о возможности асинхронного обновления состояния, в связи с чем оф. документация рекомендует использовать использовать функциональный стиль.stopTimer(){
this.setState({stopped: !this.state.stopped});
if(this.state.stopped){
clearInterval(this.timerID);
}
else
{
this.timerID = setInterval(() => this.increment(), 1000/INTERVAL);
};
}
}
Судя по названию метод должен останавливать таймер, но он его и запускает. Не должен ли он тогда называться toggleTimer()?this.timerID = setInterval(() => this.increment(), 1000/INTERVAL);
иclearInterval(this.timerID);
Повторяющийся код в данном случае можно вынести в отдельную функцию.if (this.state.stopped) document.title = "Таймер";
Вы выносите в отдельную переменную value, но не stopped. Подобные обращения на несколько уровней вложенности тяжело читать. Сделать код читабельнее и короче Вам поможет деструктуризация.Math.floor(value/INTERVAL/60/60)+":"+Math.floor(value/INTERVAL/60) % 60+":"+Math.floor(value/INTERVAL) % 60;
Подобные выражения лучше предварительно вычислять и сохранять в соответствующие переменные, тем более что их значения по коду используются несколько раз (для отображения в заголовке окна и в самом таймере).{value % INTERVAL < 10 ? '0' : ''}{value % INTERVAL}
Для добавления ведущих нулей обычно используется padStart(), преимущества которого особенно заметны в тех случаях, когда ведущих нулей больше одного. Интересно, что ведущие нули есть только у децисекунд. Если Вам было лень дублировать ту же логику для секунд/минут/и т.д. могли бы выделить ее в отдельную функцию.Также надо исправить метод increment(), чтобы он останавливался, когда stopped = true:Разве не для этого был остановлен таймер?
<div class="container-fluid align-items-center">
Оф. документация любезно просит использовать className вместо class, о чем React сигнализирует в консоли разработчика своими warning'ами.
Совместно с flexbox'ом выглядит очень прогрессивно =)Даже после исправления всех этих упрощений и ошибок (в т.ч. орфографических) статья все еще не сможет называться «Изучаем реакт», скорее «Изучаем еще один способ сделать таймер с применением реакта». Пожалуйста, не торопитесь делиться тем, в чем еще сами не до конца разобрались, тем более на ресурсе такого уровня. Подобных статей на хабре итак много, что превращает его в помойку из выброшенных велосипедов.
Для тех же, кому действительно хотелось бы изучить реакт за один день, могу посоветовать данный материал, в котором все по порядку объясняется на доступном языке и наглядном примере (есть продолжения про redux и router). И да, дня вполне хватит, чтобы его прочитать и попрактиковаться. повторив все действия автора.
Благодарю за комментарии и подробные предложения по редактуре. Как буду немного посвободней - внесу предложенные изменения в статью.
Статья писалась для начинающих, для тех, кто ни разу не пробовал React и хотел бы разобраться с ним. Да, за основу я взял официальную документацию, но там многие моменты не были расписаны или наоборот было много воды. Хотелось сжать информацию, чтобы с основами можно было ознакомиться за 10 минут, а не за день (сколько мне потребовалось на изучение документации).
То что статья кажется слабой для мидлов и синьоров - возможно. Но она писалась не для них, а для трейни и джунов, которым интересно попробовать React и решить хотят они дальше его изучать или нет.
И спасибо за ссылку - почитал, там действительно всё подробно описано.
Начать с React и Bootstrap за 2 дня. День №1