Привет!

Saber Interactive

SmartKupon (Фабрика Лояльности)

Kongsberg Interactive

Gaijin Entertainment

фрилансер на Upwork - 2 стартапа на react и redux

twitter, github - lapanoid

Сергей Лапин

Что такое Реакт

и как его готовить?

компонентный подход

                                    

 

 

 

(данные) => 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

Анимации

Что такое Реакт компонет?

  1. object getDefaultProps()
  2. object getInitialState()
  3. object propTypes
  4. array mixins
  5. object statics
  6. string displayName
  7. void componentWillMount()
  8. void componentDidMount()
  9. void componentWillReceiveProps(object nextProps)
  10. boolean shouldComponentUpdate(object nextProps, object nextState)
  11. void componentWillUpdate(object nextProps, object nextState)
  12. void componentDidUpdate(object prevProps, object prevState)
  13. void render() - обязателен
  14. void setState(function|object nextState, [function callback])
  15. void replaceState(object nextState, [function callback])
  16. void forceUpdate([function callback])
  17. DOMElement getDOMNode()
  18. boolean isMounted()
  19. void setProps(object nextProps,[function callback])
  20. void replaceProps(object nextProps,[function callback])

не рекомендуется использовать - mixins, statics, replaceState, getDOMNode, isMounted, setProps, replaceProps


displayName - для дебага

Итог: - 9 наименований

  1. object propTypes
  2. object getDefaultProps()
  3. object getInitialState()
  4. void componentWillMount() 
  5. void componentDidMount()
  6. void componentWillReceiveProps(object nextProps)
  7. boolean shouldComponentUpdate(object nextProps, object nextState)
  8. void componentWillUpdate(object nextProps, object nextState)
  9. void componentDidUpdate(object prevProps, object prevState)
  10. void render() - обязателен
  11. void setState(function|object nextState, [function callback])

 

  • 2 метода чтобы задать начальные props и state 
  • 5 lifecycle методов 
  • shouldComponentUpdate - для оптимизации
  • propTypes - чтобы проверять props на типы данных
  • render и setState - самое основное

 

  1. void render() - обязателен
  2. 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);
}

Как оптимизировать?

Made with Slides.com