Привет!
Saber Interactive
SmartKupon (Фабрика Лояльности)
Kongsberg Interactive
Gaijin Entertainment
фрилансер на Upwork - 2 стартапа на react и redux
Сергей Лапин
Что такое Реакт
и как его готовить?
компонентный подход
(данные) => UI
Виртуальный DOM эффективно обновляет DOM
var React = require('react')
var HelloWorld = React.createClass({
render: function() {
return (
<div>
Say Hello World for
{this.props.count} time
</div>
)
}
});
var React = require('react')
var SayHello2Times = React.createClass({
render: function() {
return (<div>
<HelloWorld count={1}/>
<HelloWorld count={2}/>
</div>)
}
});
React.render(<SayHello2Times/>, node)
Не только DOM, но и ...
react-native : android, iOS
Canvas
Svg
Терминал
WebGl - shader
WebGL - 3d
Анимации
Что такое Реакт компонет?
- object getDefaultProps()
- object getInitialState()
- object propTypes
- array mixins
- object statics
- string displayName
- void componentWillMount()
- void componentDidMount()
- void componentWillReceiveProps(object nextProps)
- boolean shouldComponentUpdate(object nextProps, object nextState)
- void componentWillUpdate(object nextProps, object nextState)
- void componentDidUpdate(object prevProps, object prevState)
- void render() - обязателен
- void setState(function|object nextState, [function callback])
- void replaceState(object nextState, [function callback])
- void forceUpdate([function callback])
- DOMElement getDOMNode()
- boolean isMounted()
- void setProps(object nextProps,[function callback])
- void replaceProps(object nextProps,[function callback])
не рекомендуется использовать - mixins, statics, replaceState, getDOMNode, isMounted, setProps, replaceProps
displayName - для дебага
Итог: - 9 наименований
- object propTypes
- object getDefaultProps()
- object getInitialState()
- void componentWillMount()
- void componentDidMount()
- void componentWillReceiveProps(object nextProps)
- boolean shouldComponentUpdate(object nextProps, object nextState)
- void componentWillUpdate(object nextProps, object nextState)
- void componentDidUpdate(object prevProps, object prevState)
- void render() - обязателен
- void setState(function|object nextState, [function callback])
- 2 метода чтобы задать начальные props и state
- 5 lifecycle методов
- shouldComponentUpdate - для оптимизации
- propTypes - чтобы проверять props на типы данных
- render и setState - самое основное
- void render() - обязателен
- void setState(function|object nextState, [function callback])
Если у нас нет состояния и мы только делаем render в компоненте -
stateless, pure, dumb
Если state есть -
statefull, smart
var WriteMessage = React.createClass({
getInitialState(){
return { message: "Hello" }
},
render: function() {
return (
<input type="text"
value={this.state.message}
onChange={function(event) {
this.setState({
message: event.target.value
})
}.bind(this)}/>
}
})
smart-> smart->
pure pure
smart-> pure->
pure pure
smart pure
Плохо =( Хорошо!
Храни стейт в одном месте -
на самом верху!
var WriteMessageParent = React.createClass({
render: function() {
return <div>
<WriteMessage />
<PrintMessage message={ ??? }/>
</div>
}
});
var WriteMessage = React.createClass({
handleChange: function(event) {
this.setState({ message: event.target.value })
},
render: function() {
return <input type="text"
value={this.state.message}
onChange={this.handleChange}/>
}
})
var WriteMessageParent = React.createClass({
handleWriteMessageChange: function(event) {
this.setState({ message: event.target.value })
},
render: function() {
return <div>
<WriteMessage handleChange={this.handleWriteMessageChange}/>
<PrintMessage message={this.state.message}/>
</div>
}
});
var WriteMessage = React.createClass({
render: function() {
return <input type="text"
value={this.props.message}
onChange={this.props.handleChange}/>
}
});
Реакт - простой,
но хочет быть еще проще
var React = require('react');
var MyComponent = React.createClass({
[SomeMixin],
render: function() {
return <div>Hello World {this.props.name}</div>;
}
});
React.render(<MyComponent name='react'/>, node);
import React, {Component} from 'react';
const class MyComponent extends Component {
render() {
return <div>Hello World {this.props.name}</div>;
}
});
const DecoratedComponent = SomeDecorator(MyComponent);
React.render(<DecoratedComponent name='react'/>, node);
import React from 'react';
import ReactDOM from 'react-dom';
const MyComponent = (props) => {
return <div>Hello World {props.name}</div>;
};
const DecoratedComponent = SomeDecorator(MyComponent);
ReactDOM.render(<DecoratedComponent name='react'/>, node);
import React from 'react';
import ReactDOM from 'react-dom';
const DecoratedComponent = SomeDecorator(({name}) =>
<div>Hello World {name}</div>
);
ReactDOM.render(<DecoratedComponent name='react'/>, node);
Что использовать при разработке?
- Webpack
- babel
- можно обойтись без gulp - npm scripts
- ищите компоненты тут
- установите react-devtools
- Пример проекта - тут
Что пригодится, если вы создаете приложение?
React Router держит UI в соответствии с URL.
Всегда имейте ввиду урлы при создании приложения.
render((
<Router>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="inbox" component={Inbox}>
{/* Add the route,
nested where we want the UI to nest */}
<Route path="messages/:id" component={Message}/>
</Route>
</Route>
</Router>
), document.body)
path: /inbox
+---------+------------+------------------------+
| About | Inbox | |
+---------+ +------------------------+
| Compose Reply Reply All Archive |
+-----------------------------------------------+
|Movie tomorrow| |
+--------------+ 10 Unread Messages |
|TPS Report | 22 drafts |
+--------------+ |
|New Pull Reque| |
+--------------+ |
|... | |
+--------------+--------------------------------+
path: /inbox/messages/1234
+---------+------------+------------------------+
| About | Inbox | |
+---------+ +------------------------+
| Compose Reply Reply All Archive |
+-----------------------------------------------+
|Movie tomorrow| |
+--------------+ Subject: TPS Report |
|TPS Report From: boss@big.co |
+--------------+ |
|New Pull Reque| So ... |
+--------------+ |
|... | |
+--------------+--------------------------------+
Flux
Сравнение флаксов
Используете Redux ;)
Если у вас "сложные" данные
Flow
type AppState = ViewingState | EditingState;
type ViewingState = { mode: ‘viewing’ };
type EditingState = { mode: ‘editing’; articleId: number };
class AppComponent extends React.Component {
state: AppState;
setState(newState: AppState) {
super.setState(newState);
}
...
}
- постепенное внедренение
- комьюнити сидит на js и es6
Что тестировать?
структуру
(props)-> expected render
поведение
(action scenario)-> expected state
Как тестировать?
render в DOM (браузерe - karma-webpack)
- медленный тк надо эмулировать DOM
- реакт декларативен, а тесты императивные
render без DOM (node js)
- Test Utilities
- браузерозависимый код может не взлететь css-modules, require('*.css/less/...')
Комьюнити
Ссылки
Спасибо !
shouldComponentUpdate: function(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState);
}
Как оптимизировать?
Что такое реакт и как его готовить?
By Sergey Lapin
Что такое реакт и как его готовить?
- 4,153