Witaj, świecie!
React znacznie ułatwia tworzenie interaktywnych UI. Zaprojektuj proste widoki obsługujące stan aplikacji, a React zajmie się sprawną aktualizacją i ponownym renderowaniem odpowiednich komponentów.
Deklaratywne widoki sprawiają, że kod staje się bardziej przewidywalny i łatwiejszy do debugowania.
Twórz izolowane komponenty, które zarządzają własnym stanem, a później łącz je w złożony UI.
Jako że logika komponentów pisana jest w JavaScripcie, a nie w szablonach, przekazywanie skomplikowanych struktur danych i przechowywanie stanu aplikacji poza drzewem DOM staje się łatwiejsze.
React działa w izolacji od reszty stosu technologicznego, dzięki czemu możesz w nim tworzyć nowe funkcjonalności, bez konieczności przepisywania istniejącego kodu.
React potrafi również renderować po stronie serwera przy użyciu Node, a także napędzać aplikacje mobilne za pomocą React Native.
Komponenty reactowe zawierają metodę render()
, która na podstawie danych wejściowych oblicza, co powinno zostać wyświetlone. W tym przykładzie użyliśmy podobnej do XML-a składni o nazwie JSX. Dane przekazane do komponentu można odczytać ze zmiennej this.props
.
Używanie składni JSX nie jest wymagane w Reakcie. W środowisku Babel REPL możesz podejrzeć surowy kod javascriptowy, powstały w wyniku kompilacji składni JSX.
class HelloMessage extends React.Component {
render() {
return <div>Witaj, {this.props.name}</div>;
}
}
root.render(<HelloMessage name="Michał" />);
Poza danymi wejściowymi do komponentu (dostępnymi w this.props
), komponent może zarządzać swoim wewnętrznym stanem (dostępnym w this.state
). Przy każdej zmianie stanu komponentu następuje ponownie wywołanie metody render()
, co skutkuje zaktualizowaniem wyrenderowanej struktury.
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
tick() {
this.setState(state => ({
seconds: state.seconds + 1
}));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
Sekundy: {this.state.seconds}
</div>
);
}
}
root.render(<Timer />);
Przy pomocy zmiennych props
oraz state
możemy stworzyć małą aplikację z listą zadań. Ten przykład wykorzystuje state
do śledzenia zmian w liście elementów oraz wartości z pola tekstowego. Mimo że uchwyty do obsługi zdarzeń wydają się tu być renderowane wraz z komponentem, to tak naprawdę zostaną one zebrane i odpowiednio zaimplementowane przy użyciu mechanizmu obsługi zdarzeń.
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.state = { items: [], text: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div>
<h3>Do zrobienia</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<label htmlFor="new-todo">
Co jest do zrobienia?
</label>
<input
id="new-todo"
onChange={this.handleChange}
value={this.state.text}
/>
<button>
Dodaj #{this.state.items.length + 1}
</button>
</form>
</div>
);
}
handleChange(e) {
this.setState({ text: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.text.length === 0) {
return;
}
const newItem = {
text: this.state.text,
id: Date.now()
};
this.setState(state => ({
items: state.items.concat(newItem),
text: ''
}));
}
}
class TodoList extends React.Component {
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
root.render(<TodoApp />);
React pozwala na używanie innych bibliotek i frameworków. W tym przykładzie skorzystaliśmy z remarkable, zewnętrznej biblioteki obsługującej składnię Markdown, aby w czasie rzeczywistym przekształcać wartość z pola <textarea>
.
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.md = new Remarkable();
this.handleChange = this.handleChange.bind(this);
this.state = { value: 'Witaj, **świecie**!' };
}
handleChange(e) {
this.setState({ value: e.target.value });
}
getRawMarkup() {
return { __html: this.md.render(this.state.value) };
}
render() {
return (
<div className="MarkdownEditor">
<h3>Dane wejściowe</h3>
<label htmlFor="markdown-content">
Wpisz kod z użyciem składni Markdown
</label>
<textarea
id="markdown-content"
onChange={this.handleChange}
defaultValue={this.state.value}
/>
<h3>Wynik</h3>
<div
className="content"
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
);
}
}
root.render(<MarkdownEditor />);
Witaj, świecie!