react + redux · react + redux. react ... element, created using jsx syntax “virtual dom” react...

17
“Functional UI programming” React + Redux

Upload: others

Post on 22-May-2020

100 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

“Functional UI programming”React + Redux

Page 2: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

React

› Smallest possible react application:

ReactDOM.render(

<h1>Hello, world!</h1>,

document.getElementById('root')

);

This is a React

Element, created

using JSX syntax

Page 3: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

“Virtual DOM”

React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring

the DOM to the desired state.

React only updates what’s necessary

Page 4: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

function tick() {

const element = (

<div>

<h1>Hello, world!</h1>

<h2>It is {new Date().toLocaleTimeString()}.</h2>

</div>

);

ReactDOM.render(

element,

document.getElementById('root')

);

}

setInterval(tick, 1000);

Page 5: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Components

› Simplest possible React component:

function Welcome(props) {

return <h1>Hello, {props.name}</h1>;

}

Properties argument,

contains application

data

Returns a React

Element

Page 6: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

JSX

› XML-like syntax extension to JavaScript

› Requires pre-processor

• Babel (JSX, ES6)

• Typescript (TSX)

<div>

<h1>Hello, world!</h1>

<h2>It is {new Date().toLocaleTimeString()}.</h2>

</div>

Page 7: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Compose with components

function SplitPane(props) {

return (<div className="SplitPane">

<div className="SplitPane-left">

{props.left}

</div>

<div className="SplitPane-right">

{props.right}

</div>

</div>);

}

function App() {

return (<SplitPane

left={ <Contacts/> }

right={<Chat/> }

/>);

}

Page 8: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

State flows downwards (callbacks to go up)function FormattedDate(props) {

return <h2>It is {props.date.toLocaleTimeString()}.</h2>;

}

class Clock extends React.Component {

constructor(props) {

super(props);

this.state = { date: new Date() };

}

render() {

return (

<div>

<h1>Hello, world!</h1>

<FormattedDate date={this.state.date} />

<button onClick={() => this.setState({date: new Date() })}>

Reset clock

</button>

</div>

);

}

}

ReactDOM.render(

<Clock />,

document.getElementById('root')

);

Clock

Formatted

Date button

date onClick()

date

Page 9: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Clock

Page 10: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Redux

Page 11: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Redux

Page 12: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Bare-bones Redux with RxJS: demo

Page 13: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

RxJS-based middleware for Redux

Redux-Observable

Page 14: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Epics

const suggestOnInputChangedEpic =

(action$: ActionsObservable<Actions>,

store: MiddlewareAPI<SearchState>,

services: IServices): Rx.Observable<Actions> => {

return action$

.actionsOfType<InputChangedAction>(InputChangedActionType)

.map(a => a.payload)

.debounceTime(SuggestDelay, services.scheduler)

.distinctUntilChanged()

.map(s => suggest(s, false));

};

Page 15: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

IServices injected into Epic

export interface IServices {

readonly search: ISearchService;

readonly scheduler: IScheduler;

}

const services = {

search: new SomeSearchService(),

scheduler: Rx.Scheduler.async // setup the default rx scheduler for

epics as the async scheduler, to be overriden in tests

};

const epicMiddleware = createEpicMiddleware(rootEpic, { dependencies:services });

Page 16: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Marble-testing epics with virtual timetest("suggestEpic debounces input", () => {

// Create test scheduler

const testScheduler = createTestScheduler();

// Mock services

const servicesMock = TypeMoq.Mock.ofType<IServices>();

servicesMock.setup(m => m.scheduler).returns(() => testScheduler);

const services = servicesMock.object;

// Define marble values

const inputActions = {

a: inputChanged("rr"),

b: inputChanged("rx"),

c: inputChanged("rxjs")

};

const outputActions = {

b: suggest("rx", false),

c: suggest("rxjs", false)

};

Page 17: React + Redux · React + Redux. React ... Element, created using JSX syntax “Virtual DOM” React DOM compares the element and its children to the previous one, and only applies

Marble-testing epics with virtual time

// Define marble diagrams

const inputMarble = "-ab---------------------c";

const outputMarble = "----------------------b---------------------c";

// Mock input actions stream

const action$ = createTestAction$FromMarbles<Actions>(testScheduler, inputMarble,

inputActions);

// Apply epic on actions observable

const outputAction$ = suggestOnInputChangedEpic(action$, store, services);

// Assert on the resulting actions observable

testScheduler.expectObservable(outputAction$).toBe(outputMarble, outputActions);

// Run test

testScheduler.flush();

});