[JS] Jak zaktualizować wygląd elementu po zmianie stanu atrybutu w React.js?
Ostatnio postanowiłem sprawdzić czym jest React.js? Od dłuższego czasu miałem świadomość istnienia tej biblioteki do obsługi widoków w aplikacjach JS. W trakcie testowania możliwości React.js napotkałem się z problemem aktualizacji widoku po zmianie stanu/wartości jednego z atrybutów widoku.
Problem polegał na tym, że w trakcie działania aplikacji postanowiłem aktualizować wartości wyświetlane w danym elemencie strony (na potrzeby tego tekstu załóżmy że był to licznik aktywnych użytkowników) a po aktualizacji wartości chciałem aby została uruchomiona animacja.
Szukałem rozwiązania tego problemu i okazało się (być może nie szukałem zbyt dokładnie), że React.js nie obsługuje możliwości zmiany stanu już istniejącego elementu. To znaczy, może zmieniać stan podczas dodawania elementu lub jego usuwania, ale w momencie gdy następuje aktualizacja danych, to implementacja zamierzonej animacji (chwilowe powiększenie elementu i powrót do poprzedniego wyglądu) jest niemożliwa.
Rozwiązanie problemu - aktualizacja wyglądu elementu po zmianie wartości atrybutu
Proponowane przeze mnie rozwiązanie opiera się na fakcie, że React.js monitoruje zmiany wartości klucza identyfikującego dany element - atrybut key
. Gdy następuje zmiana wartości tego atrybutu, to React.js ponownie renderuje dany element.
Kod, który jest odpowiedzialny za takie działanie wygląda następująco:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 'use strict'; var React = require('../../../node_modules/react/addons'), ReactCSSTransitionGroup = React.addons.CSSTransitionGroup, NotificationItem; (function () { NotificationItem = React.createClass({ // Obsługa sytuacji, gdy następuje aktualizacja danych widoku // W tym przypadku, aktualizuje stan licznika liczby osób componentWillReceiveProps: function (nextProps) { this.setState({usersCount: nextProps.item.users.length}); }, getInitialState: function () { return { onClick: function () { console.log('notification:click'); }, notificationType: 'default', updates: [], updatesCount: 0 }; }, render: function () { var key = this.state.notificationType + '-notification-' + this.state.usersCount; return ( <a className="notification" href="#" key={key} onClick={this.state.onClick}> <ReactCSSTransitionGroup transitionName="update"> <span className="badge new">{this.state.usersCount}</span> </ReactCSSTransitionGroup> </a> ); } }); })(); |
Do powyższego kodu JavaScript możemy dołożyć kod CSS w którym będą zdefniowane reguły odpowiedzialne za animację, np.:
1 2 3 4 5 6 7 8 9 10 | .notification { background: green; animation: notify .5s 2; } @keyframes notify { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } } |
W momencie gdy element zostanie od nowa wyrenderowany to animacja powinna się uruchomić.
Zapraszam do komentowania i dzielenia się swoimi uwagami.