[JS] Jak zaktualizować wygląd elementu po zmianie stanu atrybutu w React.js?
This post is 11 years old. Browsers and tools may have changed since then, so check the code against current documentation before you use it.
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.
Section 1Rozwią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.