
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЖрдкрдХреЛ рдХрджрдо рд╕реЗ рдХрджрдо рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ ReactJS рдореЗрдВ рд▓рд┐рдЦреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП IndexDB (рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдЬреЛ рдХрд┐рд╕реА рднреА рдЖрдзреБрдирд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ) рддреИрдпрд╛рд░ рдХрд░рдирд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЖрдк рдЗрдВрдбреЗрдХреНрд╕рдбреАрдмреА рд╕реЗ рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ
Redux рд╕реНрдЯреЛрд░ рдореЗрдВ рдерд╛ ред
IndexDB рдПрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝-
рдЙрдиреНрдореБрдЦ DBMS рд╣реИ, рдЬреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рдУрд░ рд╕рдВрд░рдЪрд┐рдд рдбреЗрдЯрд╛ рдХреА рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЫреЛрдЯреА рд░рд╛рд╢рд┐ (рдЗрдХрд╛рдЗрдпреЛрдВ рдФрд░ рдореЗрдЧрд╛рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рджрд╕рд┐рдпреЛрдВ) рдХреЗ рдЕрд╕реНрдерд╛рдпреА рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЙрдкрдХрд░рдг рд╣реИред рдЬрд┐рд╕ рдорд╛рдирдХ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ IndexDB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдЙрд╕рдореЗрдВ рдЧреНрд░рд╛рд╣рдХ рдкрдХреНрд╖ рдкрд░ рд╡реНрдпрд╛рдкрд╛рд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдбреЗрдЯрд╛ (рджреЗрд╢реЛрдВ, рд╢рд╣рд░реЛрдВ, рдХреЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореБрджреНрд░рд╛рдПрдВ, рдЖрджрд┐) рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдХреЙрдкреА рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдХреЗрд╡рд▓ рд╕рд░реНрд╡рд░ (рдпрд╛ рд╕рдВрдкреВрд░реНрдг - рд╡реЗ рдЫреЛрдЯреЗ рд╣реИрдВ) рд╕реЗ рдЗрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рд╕реЗ рдЕрдкрдбреЗрдЯ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рд░ рдмрд╛рд░ рдЬрдм рдЖрдк рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡рд┐рдВрдбреЛ рдЦреЛрд▓рддреЗ рд╣реИрдВ рддреЛ рдРрд╕рд╛ рди рдХрд░реЗрдВред
IndexDB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреИрд░-рдорд╛рдирдХ, рдмрд╣реБрдд рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж, рд▓реЗрдХрд┐рди рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╣реИрдВ:
- рд╕рднреА рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдХреИрд╢рд┐рдВрдЧ рдХрд░рдирд╛ рддрд╛рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕рд╛рдЗрдб рдкрд░ рд╡реНрдпрд╛рдкрдХ рдЫрдВрдЯрд╛рдИ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛ
- Redux рд╕реНрдЯреЛрд░ рдХреЗ рдмрдЬрд╛рдп IndexDB рдореЗрдВ рдЖрд╡реЗрджрди рдХреА рд╕реНрдерд┐рддрд┐
IndexDB рдФрд░ Redux Store рдХреЗ рдмреАрдЪ рддреАрди рдкреНрд░рдореБрдЦ рдЕрдВрддрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВ:
- IndexDB рдПрдХ рдмрд╛рд╣рд░реА рд╕рдВрдЧреНрд░рд╣рдг рд╣реИ рдЬрд┐рд╕реЗ рдкреГрд╖реНрда рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╕рдордп рд╕рд╛рдлрд╝ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдХрдИ рдЦреБрд▓реЗ рдЯреИрдм рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИ (рдЬреЛ рдХрднреА-рдХрднреА рдХреБрдЫ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ)
- IndexDB рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ DBMS рд╣реИред рд╕рднреА рдСрдкрд░реЗрд╢рди - рдЦреЛрд▓рдирд╛, рдкрдврд╝рдирд╛, рд▓рд┐рдЦрдирд╛, рдЦреЛрдЬрдирд╛ - рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХред
- IndexDB JSON рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд (рддреБрдЪреНрдЫ рддрд░реАрдХреЗ рд╕реЗ) рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕реНрдиреИрдкрд╢реЙрдЯ рдмрдирд╛рдиреЗ, рдбреАрдмрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЖрд╕рд╛рдиреА рдФрд░ рдЕрддреАрдд рдореЗрдВ рдпрд╛рддреНрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Redux рд╕реЗ рдорд╕реНрддрд┐рд╖реНрдХ-рдЪрд╛рд▓рд┐рдд рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЪрд░рдг 0: рдХрд╛рд░реНрдп рд╕реВрдЪреА
рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдПрдХ рдХреНрд▓рд╛рд╕рд┐рдХ рдЙрджрд╛рд╣рд░рдгред рд╡рд░реНрддрдорд╛рди рдФрд░ рдПрдХрдорд╛рддреНрд░ рдШрдЯрдХ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд░рд╛рдЬреНрдп рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЗ рд╕рд╛рде рднрд┐рдиреНрдирддрд╛
рдХрд┐рд╕реА рдХрд╛рд░реНрдп рд╕реВрдЪреА рдШрдЯрдХ рдХреЗ рдШрдЯрдХ рд░рд╛рдЬреНрдп рдореЗрдВ рд╕реВрдЪреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиimport React, { PureComponent } from 'react'; import Button from 'react-bootstrap/Button'; import counter from 'common/counter'; import Form from 'react-bootstrap/Form'; import Table from 'react-bootstrap/Table'; export default class Step0 extends PureComponent { constructor() { super( ...arguments ); this.state = { newTaskText: '', tasks: [ { id: counter(), text: 'Sample task' }, ], }; this.handleAdd = () => { this.setState( state => ( { tasks: [ ...state.tasks, { id: counter(), text: state.newTaskText } ], newTaskText: '', } ) ); }; this.handleDeleteF = idToDelete => () => this.setState( state => ( { tasks: state.tasks.filter( ( { id } ) => id !== idToDelete ), } ) ); this.handleNewTaskTextChange = ( { target: { value } } ) => this.setState( { newTaskText: value || '', } ); } render() { return <Table bordered hover striped> <thead><tr> <th>#</th><th>Text</th><th /> </tr></thead> <tbody> { this.state.tasks.map( task => <tr key={task.id}> <td>{task.id}</td> <td>{task.text}</td> <td><Button onClick={this.handleDeleteF( task.id )} type="button" variant="danger"></Button></td> </tr> ) } <tr key="+1"> <td /> <td><Form.Control onChange={this.handleNewTaskTextChange} placeholder=" " type="text" value={this.state.newTaskText || ''} /></td> <td><Button onClick={this.handleAdd} type="button" variant="primary"></Button></td> </tr> </tbody> </Table>; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЕрдм рддрдХ, рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рднреА рдСрдкрд░реЗрд╢рди рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╣реИрдВред рдпрджрд┐ рдХрд┐рд╕реА рдХрд╛рд░реНрдп рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ 3 рд╕реЗрдХрдВрдб рд▓рдЧрддреЗ рд╣реИрдВ, рддреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдмрд╕ 3 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдлреНрд░реАрдЬ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдмреЗрд╢рдХ, рдЬрдм рд╣рдо рдЕрдкрдиреА рдпрд╛рджрджрд╛рд╢реНрдд рдореЗрдВ рд╕рдм рдХреБрдЫ рд░рдЦрддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪ рд╕рдХрддреЗред рдЬрдм рд╣рдо рдХрд┐рд╕реА рд╕рд░реНрд╡рд░ рдпрд╛ рдХрд┐рд╕реА рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рд╕реБрдВрджрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде-рд╕рд╛рде рджреЗрдЦрднрд╛рд▓ рднреА рдХрд░рдиреА рд╣реЛрдЧреАред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рддрддреНрд╡реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдпрд╛ рд╣рдЯрд╛рдиреЗ рдХреЗ рджреМрд░рд╛рди рдПрдХ рддрд╛рд▓рд┐рдХрд╛ (рдпрд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рддрддреНрд╡реЛрдВ) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдирд╛ред
рднрд╡рд┐рд╖реНрдп рдореЗрдВ UI рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рдирд╣реАрдВ рджреЛрд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдХрд╛рд░реНрдпрд╕реВрдЪреА рдШрдЯрдХ рдореЗрдВ рд░рдЦреЗрдВрдЧреЗ, рдЬрд┐рд╕рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдХрд╛рд░реНрдп рдХрд╛рд░реНрдп рд╕реВрдЪреА рдХрд╛ HTML рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред рдЙрд╕реА рд╕рдордп, рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рдмрдЯрди рдХреЛ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк рдмрдЯрди рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЖрд╡рд░рдг рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрдВрдЧреЗ, рдЬреЛ рдмрдЯрди рдХреЛ рддрдм рддрдХ рдЕрд╡рд░реБрджреНрдз рдХрд░реЗрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдмрдЯрди рд╣реИрдВрдбрд▓рд░ рдЕрдкрдиреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдпрд╣ рд╣реИрдВрдбрд▓рд░ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рд╣реЛред
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХрд╛рд░реНрдп рд╕реВрдЪреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рдШрдЯрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ import React, { PureComponent } from 'react'; import counter from 'common/counter'; import TaskList from '../common/TaskList'; export default class Step01 extends PureComponent { constructor() { super( ...arguments ); this.state = { tasks: [ { id: counter(), text: 'Sample task' }, ] }; this.handleAdd = newTaskText => { this.setState( state => ( { tasks: [ ...state.tasks, { id: counter(), text: newTaskText } ], } ) ); }; this.handleDelete = idToDelete => this.setState( state => ( { tasks: state.tasks.filter( ( { id } ) => id !== idToDelete ), } ) ); } render() { return <> <h1> </h1> <h2> </h2> <TaskList onAdd={this.handleAdd} onDelete={this.handleDelete} tasks={this.state.tasks} /> </>; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдПрдХ рдШрдЯрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЬреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирдпрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлреЙрд░реНрдо рд╣реЛрддрд╛ рд╣реИ import React, { PureComponent } from 'react'; import Button from './AutoDisableButtonWithSpinner'; import Form from 'react-bootstrap/Form'; import Table from 'react-bootstrap/Table'; export default class TaskList extends PureComponent { constructor() { super( ...arguments ); this.state = { newTaskAdding: false, newTaskText: '', }; this.handleAdd = async() => { this.setState( { newTaskAdding: true } ); try {
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирдореВрдирд╛ рдХреЛрдб рдореЗрдВ рдЖрдк рдХреАрд╡рд░реНрдб async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред Async / рдкреНрд░рддреАрдХреНрд╖рд╛рд░рдд рдирд┐рд░реНрдорд╛рдг рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдХреАрд╡рд░реНрдб рдЖрдкрдХреЛ рдкреНрд░реЛрдорд┐рд╕ рд▓реМрдЯрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдПрдХ рдирд┐рдпрдорд┐рдд рдлрд╝рдВрдХреНрд╢рди рдерд╛ (рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рддрдм () рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ)ред рдмреЗрд╢рдХ, рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдЬрд╛рджреБрдИ рд░реВрдк рд╕реЗ рдПрдХ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ, рдФрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рд╖реНрдкрд╛рджрди рдереНрд░реЗрдб рдХреЛ рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рд╡реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рддрдм рдХреЛрдб рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдФрд░ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реВрдк рдореЗрдВ рдФрд░ рдХреЛрд╢рд┐рд╢ / рдкрдХрдбрд╝рдиреЗ / рдЕрдВрдд рдореЗрдВ рдирд┐рд░реНрдорд╛рдг рджреЛрдиреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
TaskList
рди рдХреЗрд╡рд▓
TaskList
рд╣реИрдВрдбрд▓рд░ рдХреЛ
рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣
await
рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрджрд┐ рд╣реИрдВрдбрд▓рд░ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рд▓реМрдЯрд╛рдПрдЧрд╛, рдпрд╛
Promise
рдЕрд▓рд╛рд╡рд╛ рдХрд┐рд╕реА рднреА рдореВрд▓реНрдп рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдЧрд╛, рддреЛ
TaskList
рдШрдЯрдХ рдмрд╕ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ
handleAdd
рд╡рд┐рдзрд┐ рдХреЛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣реИрдВрдбрд▓рд░
Promise
рд▓реМрдЯрд╛рддрд╛ рд╣реИ (рдпрджрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХ async рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рддреЛ
TaskList
рд╣реИрдВрдбрд▓рд░ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдЧрд╛, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА
newTaskAdding
рдФрд░
newTaskText
рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░реЗрдЧрд╛ред
рдЪрд░рдг 1: рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдореЗрдВ IndexDB рдЬреЛрдбрд╝реЗрдВ
рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рд╣рдо рдПрдХ рд╕рд░рд▓ рдШрдЯрдХ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:
- рддреБрдЪреНрдЫ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдЦреЛрд▓рдиреЗ
- рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ
- рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЖрдЗрдЯрдо рдЬреЛрдбрд╝рдирд╛
рдкрд╣рд▓рд╛ рд╕рдмрд╕реЗ "рдЧреИрд░-рддреБрдЪреНрдЫ" рд╣реИ - 5 рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд░реВрдк рдореЗрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдИ рд░реЙрдХреЗрдЯ рд╕рд╛рдЗрдВрд╕ рдирд╣реАрдВ:
OpenDatabasePromise () - рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдЦреЛрд▓реЗрдВ function openDatabasePromise( keyPath ) { return new Promise( ( resolve, reject ) => { const dbOpenRequest = window.indexedDB.open( DB_NAME, '1.0.0' ); dbOpenRequest.onblocked = () => { reject( ' , , ' + ' .' ); }; dbOpenRequest.onerror = err => { console.log( 'Unable to open indexedDB ' + DB_NAME ); console.log( err ); reject( ' , .' + ( err.message ? ' : ' + err.message : '' ) ); }; dbOpenRequest.onupgradeneeded = event => { const db = event.target.result; try { db.deleteObjectStore( OBJECT_STORE_NAME ); } catch ( err ) { console.log( err ); } db.createObjectStore( OBJECT_STORE_NAME, { keyPath } ); }; dbOpenRequest.onsuccess = () => { console.info( 'Successfully open indexedDB connection to ' + DB_NAME ); resolve( dbOpenRequest.result ); }; dbOpenRequest.onerror = reject; } ); }
getAllPromise / getPromise / putPromise - рдкреНрд░реЛрдкрд░ рдореЗрдВ рд░реИрдкрд░ IndexDb рдХреЙрд▓ рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рдПрдХ IndexedDbRepository рд╡рд░реНрдЧ рдореЗрдВ рд▓рд╛рдирд╛
IndexedDbRepository - IDBDatabase рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЖрд╡рд░рдг const DB_NAME = 'objectStore'; const OBJECT_STORE_NAME = 'objectStore'; export default class IndexedDbRepository { constructor( keyPath ) { this.error = null; this.keyPath = keyPath;
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЕрдм рдЖрдк IndexDB рдХреЛ рдХреЛрдб рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
const db = new IndexedDbRepository( 'id' );
рдЗрд╕ "рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА" рдХреЛ рд╣рдорд╛рд░реЗ рдШрдЯрдХ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрдореНрдкреЛрдиреЗрдВрдЯрдбрд┐рдорд╛рдЙрдВрдЯ () рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:
import IndexedDbRepository from '../common/IndexedDbRepository'; componentDidMount() { this.repository = new IndexedDbRepository( 'id' );
рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ, ComponentsDidMount
componentDidMount()
рдлрд╝рдВрдХреНрд╢рди рдХреЛ async рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдлрд┐рд░ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдм () рдХреЗ рдмрдЬрд╛рдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА
componentDidMount()
"рд╣рдорд╛рд░рд╛" рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд░рд┐рдПрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреМрди рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ 17.x рд▓рд╛рдЗрдмреНрд░реЗрд░реА
undefined
рдмрдЬрд╛рдп
Promise
рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧреА?
рдЕрдм рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ, рдЗрд╕реЗ рдЦрд╛рд▓реА рд╕рд░рдгреА (рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рдгреА) рдХреЗ рд╕рд╛рде рднрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЗрд╕реЗ рд╢реВрдиреНрдп рд╕реЗ рднрд░ рджреЗрдВрдЧреЗред рдФрд░ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдореЗрдВ, рдпрд╣ рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдЕрд╢рдХреНрдд рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдЧрд╛ред рдЬреЛ рд▓реЛрдЧ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЗрд╕реЗ рдЕрд▓рдЧ рдЭрдВрдбреЗ рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдВрд╕реНрдерд╛рдУрдВ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХреНрдпреЛрдВ рдХрд░рддреЗ рд╣реИрдВ?
constructor() { super( ...arguments ); this.state = { tasks: null }; } render() { if ( this.state.tasks === null ) return <><Spinner animation="border" aria-hidden="true" as="span" role="status" /><span> ...</span></>; /* ... */ }
рдпрд╣
handleAdd
рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ /
handleDelete
:
constructor() { this.handleAdd = async( newTaskText ) => { await this.repository.save( { id: counter(), text: newTaskText } ); this.setState( { tasks: null } ); this.setState( { tasks: await this.repository.findAll() } ); }; this.handleDelete = async( idToDelete ) => { await this.repository.deleteById( idToDelete ); this.setState( { tasks: null } ); this.setState( { tasks: await this.repository.findAll() } ); }; }
рджреЛрдиреЛрдВ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рдПрдХ рдЖрдЗрдЯрдо рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдпрд╛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рд╡рд░реНрддрдорд╛рди рдШрдЯрдХ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдПрдХ рдирдИ рд╕реВрдЪреА рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реЗрдЯрд╕реНрдЯреИрдЯ () рдкрд░ рдХреЙрд▓ рдПрдХ рдХреЗ рдмрд╛рдж рдПрдХ рдЬрд╛рдПрдЧреАред рд▓реЗрдХрд┐рди рд╣реИрдВрдбрд▓рд░ рдХреА рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдХреАрд╡рд░реНрдб рджреВрд╕рд░реА рд╕реЗрдЯрд╕реНрдЯреИрдЯ () рдХреЙрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реЙрдорд┐рд╕ () рд╡рд┐рдзрд┐ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЪрд░рдг 2. рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рд╕реБрдиреЗрдВ
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдореЗрдВ рдПрдХ рдмрдбрд╝рд╛ рджреЛрд╖ рдпрд╣ рд╣реИ рдХрд┐, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдореЗрдВ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред рджреВрд╕рд░реЗ, рдпрджрд┐ рдПрдХ рдШрдЯрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓рддрд╛ рд╣реИ, рддреЛ рджреВрд╕рд░реЗ рдШрдЯрдХ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рддрдм рддрдХ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓рддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд░рд╛рдЬреНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред
рдЗрд╕рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирдП рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрдирд░ рдШрдЯрдХ рдХреЛ рдкреЗрд╢ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рджреЛ рдХрд╛рдо рдХрд░рдиреЗ рджреЗрдВрдЧреЗред рдпрд╣ рдШрдЯрдХ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗ рд╕рдХреЗрдЧрд╛ред рджреВрд╕рд░реЗ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрдирд░ рдЙрд╕ рдШрдЯрдХ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░реЗрдЧрд╛ рдЬрд┐рд╕рдиреЗ рдЗрд╕реЗ рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдмрдирд╛рдпрд╛ рдерд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, IndexedDbRepository рдореЗрдВ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдирд╛:
export default class IndexedDbRepository { constructor( keyPath ) { this.listeners = new Set(); this.stamp = 0; } addListener( listener ) { this.listeners.add( listener ); } onChange() { this.stamp++; this.listeners.forEach( listener => listener( this.stamp ) ); } removeListener( listener ) { this.listeners.delete( listener ); } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рд╣рдо рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХ рд╕реНрдЯрд╛рдВрдк рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╣рд░ рдХреЙрд▓ рдХреЗ рд╕рд╛рде onChange () рдореЗрдВ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рд╣рдо _tx рд╡рд┐рдзрд┐ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд░реАрдб рд░рд╛рдЗрдЯ рдореЛрдб рдХреЗ рд╕рд╛рде рд▓реЗрдирджреЗрди рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП onChange
onChange()
рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдП:
async _tx( txMode, callback ) { await this.openDatabasePromise;
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЕрдЧрд░ рд╣рдо рдЕрднреА рднреА
then()
/
catch()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░реЙрдорд┐рд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╛ рддреЛ
onChange()
рдХреЛ рдХреЙрд▓ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрд╛ рдкреНрд░реЛрдорд┐рд╕ () рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рдкреЙрд▓реАрдлрд╝рд┐рд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ
final()
рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдЖрдкрдХреЛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдХреЛрдб рдХреЗ рдпрд╣ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред
рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрд░реНрди рдШрдЯрдХ рд╕реНрд╡рдпрдВ рдПрдХ рдИрд╡реЗрдВрдЯ рд╢реНрд░реЛрддрд╛ рдХреЛ рдХрдВрдкреЛрдиреЗрдВрдЯрдбрд┐рдорд╛рдЙрдВрдЯ рдФрд░ рдХрдВрдкреЛрдиреЗрдВрдЯрд╡рд┐рд▓рд╛рдЙрдиреНрдорд╛рдЙрдВрдЯ рддрд░реАрдХреЛрдВ рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИ:
рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрдирд░ рдХреЛрдб import IndexedDbRepository from './IndexedDbRepository'; import { PureComponent } from 'react'; export default class RepositoryListener extends PureComponent { constructor() { super( ...arguments ); this.prevRepository = null; this.repositoryListener = repositoryStamp => this.props.onChange( repositoryStamp ); } componentDidMount() { this.subscribe(); } componentDidUpdate() { this.subscribe(); } componentWillUnmount() { this.unsubscribe(); } subscribe() { const { repository } = this.props; if ( repository instanceof IndexedDbRepository && this.prevRepository !== repository ) { if ( this.prevRepository !== null ) { this.prevRepository.removeListener( this.repositoryListener ); } this.prevRepository = repository; repository.addListener( this.repositoryListener ); } } unsubscribe( ) { if ( this.prevRepository !== null ) { this.prevRepository.removeListener( this.repositoryListener ); this.prevRepository = null; } } render() { return this.props.children || null; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЕрдм, рд╣рдо рдЕрдкрдиреЗ рдореБрдЦреНрдп рдШрдЯрдХ рдореЗрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВрдЧреЗ, рдФрд░,
DRY рд╕рд┐рджреНрдзрд╛рдВрдд рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд, рд╣рдо
handleAdd
/
handleDelete
рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджреЗрдВрдЧреЗ:
constructor() { super( ...arguments ); this.state = { tasks: null }; this.handleAdd = async( newTaskText ) => { await this.repository.save( { id: counter(), text: newTaskText } ); }; this.handleDelete = async( idToDelete ) => { await this.repository.deleteById( idToDelete ); }; this.handleRepositoryChanged = async() => { this.setState( { tasks: null } ); this.setState( { tasks: await this.repository.findAll() } ); }; } componentDidMount() { this.repository = new IndexedDbRepository( 'id' ); this.handleRepositoryChanged();
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдФрд░ рд╣рдо рдХрдиреЗрдХреНрдЯреЗрдб рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрд░реНрди рд╕реЗ рд╣реИрдВрдбреНрд░рд┐рдкреЗрдЯрд░реАрдЪрд╛рд░реНрдЬ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
render() { return <RepositoryListener onChange={this.handleRepoChanged} repository={this.repository}> <TaskList onAdd={this.handleAdd} onDelete={this.handleDelete} tasks={this.state.tasks} /> </RepositoryListener>; }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЪрд░рдг 3. рдбреЗрдЯрд╛ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЙрд╕рдХреЗ рдЕрджреНрдпрддрди рдХреЛ рдПрдХ рдЕрд▓рдЧ рдШрдЯрдХ рдореЗрдВ рдирд┐рдХрд╛рд▓реЗрдВ
рд╣рдордиреЗ рдПрдХ рдШрдЯрдХ рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк 100+ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐
рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдЬреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЙрд╕реЗ рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
- рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рднрдВрдбрд╛рд░ рдПрдХрд▓ рдмрд┐рдВрджреБ рд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ
- ComponentsDidMount
componentDidMount()
рд╡рд┐рдзрд┐ рдореЗрдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдбреЗрдЯрд╛ рд▓реЛрдбрд┐рдВрдЧ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ RepositoryListener
рдШрдЯрдХ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ, рдЬреЛ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЛ рдкреБрдирдГ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓рд░ рдХреЙрд▓ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ
рдХреНрдпрд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реИрдВ? рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ред рдФрд░ рдЕрдЧрд░ рдХреБрдЫ рднреВрд▓ рдЧрдпрд╛ рд╣реИ? рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдЦреЛ рдЬрд╛рдУ?
рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдо рдПрдХ рдмрд╛рд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рдпрдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдХреБрдЫ рдЬрд╛рджреБрдИ рдЗрди рддрд░реАрдХреЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рд╣рдореЗрдВ рдбреЗрдЯрд╛ рджреЗрддрд╛ рд╣реИ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдмрджрд▓рддрд╛ рд╣реИ, рдФрд░ рдвреЗрд░ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЗрд╕реЗ рдХрдиреЗрдХреНрдЯ рднреА рдХрд░ рд╕рдХрддрд╛ рд╣реИ рднрдВрдбрд╛рд░ред
this.doFindAllTasks = ( repo ) => repo.findAll(); <DataProvider doCalc={ this.doFindAllTasks }> {(data) => <span>... -, data...</span>} </DataProvider>
рдЗрд╕ рдШрдЯрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕рдордп рд╣реИ рдХрд┐ doFindAllTasks () рд╡рд╛рджрд╛ рд╣реИред рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЕрд▓рдЧ рдШрдЯрдХ рдмрдирд╛рдПрдВрдЧреЗ, рдЬреЛ рдПрдХ рдкрд░рд┐рдХрд▓рд┐рдд рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рд╡рдВрд╢ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдФрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рджреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ:
PromiseComponent рдХреЛрдб import { PureComponent } from 'react'; export default class PromiseComponent extends PureComponent { constructor() { super( ...arguments ); this.state = { error: null, value: null, }; this.prevPromise = null; } componentDidMount() { this.subscribe(); } componentDidUpdate( ) { this.subscribe(); } componentWillUnmount() { this.unsubscribe(); } subscribe() { const { cleanOnPromiseChange, promise } = this.props; if ( promise instanceof Promise && this.prevPromise !== promise ) { if ( cleanOnPromiseChange ) this.setState( { error: null, value: null } ); this.prevPromise = promise; promise.then( value => { if ( this.prevPromise === promise ) { this.setState( { error: null, value } ); } } ) .catch( error => { if ( this.prevPromise === promise ) { this.setState( { error, value: null } ); } } ); } } unsubscribe( ) { if ( this.prevPromise !== null ) { this.prevPromise = null; } } render() { const { children, fallback } = this.props; const { error, value } = this.state; if ( error !== null ) { throw error; } if ( value === undefined || value === null ) { return fallback || null; } return children( value ); } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдЗрд╕рдХреЗ рддрд░реНрдХ рдФрд░ рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдпрд╣ рдШрдЯрдХ рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрдирд░ рдХреЗ рд╕рдорд╛рди рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рджреЛрдиреЛрдВ рдПрдХ рдФрд░ рджреВрд╕рд░реЗ рдХреЛ "рд╕рд╛рдЗрди" рдХрд░рдирд╛, рдШрдЯрдирд╛рдУрдВ рдХреЛ "рд╕реБрдирдирд╛" рдФрд░ рдХрд┐рд╕реА рддрд░рд╣ рдЙрдиреНрд╣реЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдФрд░ рдпрд╣ рднреА рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдЬрд┐рдирдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЖрдкрдХреЛ рд╕реБрдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрд╣реБрдд рд╣реА рдЬрд╛рджреБрдИ рдШрдЯрдХ DataProvider рдЕрдм рддрдХ рдмрд╣реБрдд рд╕рд░рд▓ рджрд┐рдЦрддрд╛ рд╣реИ:
import repository from './RepositoryHolder'; export default class DataProvider extends PureComponent { constructor() { super( ...arguments ); this.handleRepoChanged = () => this.forceUpdate(); } render() { return <RepositoryListener onChange={this.handleRepoChanged} repository={repository}> <PromiseComponent promise={this.props.doCalc( repository )}> {data => this.props.children( data )} </PromiseComponent> </RepositoryListener>; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдордиреЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА (рдФрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рд┐рдВрдЧреНрд▓реЛрдирдЯрди рд░рд┐рдкреЛрдЬрд┐рдЯрд░реАрд╣реЛрд▓реНрдбрд░, рдЬреЛ рдЕрдм рдЖрдпрд╛рдд рдореЗрдВ рд╣реИ) рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ doCalc рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рд╣рдореЗрдВ рдХрд╛рд░реНрдп рдбреЗрдЯрд╛ рдХреЛ рдЗрд╕ .props.children рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдФрд░ рдЗрд╕рд▓рд┐рдП, рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рддреИрдпрд╛рд░ рдХрд░реЗрдВред рд╕рд┐рдВрдЧрд▓реЗрдВрдЯрди рднреА рд╕рд░рд▓ рджрд┐рдЦрддрд╛ рд╣реИ:
const repository = new IndexedDbRepository( 'id' ); export default repository;
рдЕрдм DataProvider рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рдХреЙрд▓ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЙрд▓ рдХреЛ рдмрджрд▓реЗрдВ:
import repository from './RepositoryHolder'; export default class Step3 extends PureComponent { constructor() { super( ...arguments ); this.doFindAllTasks = repository => repository.findAll(); } render() { return <DataProvider doCalc={this.doFindAllTasks} fallback={<><Spinner animation="border" aria-hidden="true" as="span" role="status" /><span> ...</span></>}> { tasks => <TaskList onAdd={this.handleAdd} onDelete={this.handleDelete} tasks={tasks} /> } </DataProvider>; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдпрд╣ рд░реБрдХ рд╕рдХрддрд╛ рдерд╛ред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдирд┐рдХрд▓рд╛: рд╣рдо рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рдЕрд▓рдЧ рдШрдЯрдХ рдЗрд╕ рдбреЗрдЯрд╛ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рд╛рдкреНрддрд┐ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЕрджреНрдпрддрди рднреА рдХрд░рддрд╛ рд╣реИред рд╡рд╕реНрддреБрддрдГ рдЫреЛрдЯреА-рдЫреЛрдЯреА рдмрд╛рддреЗрдВ рдереАрдВ:
- рдкреНрд░рддреНрдпреЗрдХ рдбреЗрдЯрд╛ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП, рдХреЛрдб рдореЗрдВ рдХрд╣реАрдВ (рд▓реЗрдХрд┐рди
render()
рд╡рд┐рдзрд┐ рдореЗрдВ рдирд╣реАрдВ render()
рдЖрдкрдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдбреЗрдЯрд╛рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВ - DataProvider рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рднрд╛рд╡рдирд╛ рдореЗрдВ рдорд╣рд╛рди рдФрд░ рдХрд╛рдлреА рд╣реИ, рд▓реЗрдХрд┐рди JSX рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдмрд╣реБрдд рдмрджрд╕реВрд░рдд рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рдШрдЯрдХ рд╣реИрдВ, рддреЛ рд╡рд┐рднрд┐рдиреНрди DataProviders рдХреЗ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХреЗ рджреЛ рдпрд╛ рддреАрди рд╕реНрддрд░ рдЖрдкрдХреЛ рдмрд╣реБрдд рднреНрд░рдорд┐рдд рдХрд░реЗрдВрдЧреЗред
- рдпрд╣ рджреБрдЦрдж рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдПрдХ рдШрдЯрдХ (рдбреЗрдЯрд╛рдкреНрд░реЛрдЗрдбрд░) рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЙрдирдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рджреВрд╕рд░реЗ (рдореБрдЦреНрдп рдШрдЯрдХ) рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдЙрд╕реА рддрдВрддреНрд░ рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред
рдЪрд░рдг 4. рдХрдиреЗрдХреНрдЯ ()
рд╢реАрд░реНрд╖рдХ рдХреЗ рд╢реАрд░реНрд╖рдХ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд┐рдбреНрдпреВрдХреНрд╕ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВ рдмрд╛рдХреА рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рджреЗрдЧрд╛: рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐, рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдмрдЪреНрдЪреЛрдВ () рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдбреЗрдЯрд╛рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рд╕реЗрд╡рд╛ рдШрдЯрдХ рдирд┐рдпрдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣рдорд╛рд░реЗ рдШрдЯрдХ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рднрд░ рджреЗрдЧрд╛ред рдФрд░ рдЕрдЧрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдХреБрдЫ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рдмрд╕ рдорд╛рдирдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рддрдВрддреНрд░ рдХреЗ рд╕рд╛рде рдЧреБрдгреЛрдВ рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛ред
рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рд╣рд╛рдпрд░ рдСрд░реНрдбрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдПрдХ рдШрдЯрдХ рд╡рд░реНрдЧ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдФрд░, рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдШрдЯрдХ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдп рдЬреЛ рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ рд╡рд╣ рд╣реЛрдЧрд╛:
- рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдШрдЯрдХ рд╡рд░реНрдЧ рд▓реЗрдВ рдЬрд╣рд╛рдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ
- рдирд┐рдпрдореЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдВ, рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рдФрд░ рдЗрд╕реЗ рдХрд┐рд╕ рдЧреБрдгреЛрдВ рдореЗрдВ рдбрд╛рд▓реЗрдВ
- рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдореЗрдВ, рдпрд╣ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд┐рдбрдХреНрд╕ рд╕реЗ рдХрдиреЗрдХреНрдЯ () рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реЛрдЧрд╛ред
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХреЙрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:
const mapRepoToProps = repository => ( { tasks: repository.findAll(), } ); const mapRepoToActions = repository => ( { doAdd: ( newTaskText ) => repository.save( { id: counter(), text: newTaskText } ), doDelete: ( idToDelete ) => repository.deleteById( idToDelete ), } ); const Step4Connected = connect( mapRepoToProps, mapRepoToActions )( Step4 );
рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐рдпрд╛рдБ
Step4
рдШрдЯрдХ рдХреЗ рдЧреБрдг рдирд╛рдо рдФрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рд▓реЛрдб рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдорд╛рдиреЛрдВ рдХреЗ рдмреАрдЪ рдореИрдкрд┐рдВрдЧ рдХреЛ
Step4
рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдореИрдкрд┐рдВрдЧ рдЖрддреА рд╣реИ: рдпрджрд┐
Step4
рдШрдЯрдХ рдХреЗ рднреАрддрд░
this.props.doDelete(...)
this.props.doAdd(...)
рдпрд╛
this.props.doDelete(...)
рдХреЛ рдХреЙрд▓
Step4
рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ред рдФрд░ рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рд▓рд╛рддреА рд╣реИ рдФрд░ рдХрдиреЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреА рд╣реИред рдкрд░рд┐рдгрд╛рдо рдПрдХ рдирдпрд╛ рдШрдЯрдХ рд╣реИ (рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рддрдХрдиреАрдХ рдХреЛ рд╣рд╛рдпрд░ рдСрд░реНрдбрд░ рдХрдВрдкреЛрдиреЗрдВрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рдФрд░ рд╣рдо рдЕрдм рдореВрд▓ Step4 рдШрдЯрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЖрд╡рд░рдг:
class Step4 extends PureComponent { } const Step4Connected = connect( )( Step4 ); export default Step4Connected;
рдФрд░ рдЯрд╛рд╕реНрдХрд▓рд┐рд╕реНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдШрдЯрдХ рдЕрдм рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЖрд╡рд░рдг рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
class Step4 extends PureComponent { render() { return this.props.tasks === undefined || this.props.tasks === null ? <><Spinner animation="border" aria-hidden="true" as="span" role="status" /><span> ...</span></> : <TaskList onAdd={this.props.doAdd} onDelete={this.props.doDelete} tasks={this.props.tasks} />; } }
(
рдЬреАрдереВрдм рд╕реЛрд░реНрд╕ рдХреЛрдб )
рдФрд░ рд╡рд╣ рдпрд╣ рд╣реИред рдХреЛрдИ рдирд┐рд░реНрдорд╛рддрд╛, рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд╣реИрдВрдбрд▓рд░ рдирд╣реАрдВ - рдШрдЯрдХ рдХреЗ рдкреНрд░реЙрдкрд░ рдореЗрдВ рдХрдиреЗрдХреНрдЯ () рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╕рдм рдХреБрдЫ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИред
рдпрд╣ рджреЗрдЦрдирд╛ рдмрд╛рдХреА рд╣реИ рдХрд┐ рдХрдиреЗрдХреНрдЯ () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреИрд╕реЗ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдХрдиреЗрдХреНрдЯ () рдХреЛрдб import repository from './RepositoryHolder'; class Connected extends PureComponent { constructor() { super( ...arguments ); this.handleRepoChanged = () => this.forceUpdate(); } render() { const { childClass, childProps, mapRepoToProps, mapRepoToActions } = this.props; const promises = mapRepoToProps( repository, childProps ); const actions = mapRepoToActions( repository, childProps ); return <RepositoryListener onChange={this.handleRepoChanged} repository={repository}> <PromisesComponent promises={promises}> { values => React.createElement( childClass, { ...childProps, ...values, ...actions, } )} </PromisesComponent> </RepositoryListener>; } } export default function connect( mapRepoToProps, mapRepoToActions ) { return childClass => props => <Connected childClass={childClass} childProps={props} mapRepoToActions={mapRepoToActions} mapRepoToProps={mapRepoToProps} />; }
(
рдЬреАрдереБрдм рд╕реНрд░реЛрдд рдХреЛрдб )
рдХреЛрдб рднреА рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ ... рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрджрд┐ рдЖрдк рдбрд╛рдЗрд╡рд┐рдВрдЧ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рд╡рд╛рд▓ рдЙрдареЗрдВрдЧреЗред рдЖрдкрдХреЛ рдЕрдВрдд рд╕реЗ рдкрдврд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдпрд╣ рд╡рд╣рд╛рдБ рд╣реИ рдХрд┐
connect()
рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред рдпрд╣ рджреЛ рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬреЛ рд╡рд╛рдкрд╕ рд▓реМрдЯрддрд╛ рд╣реИ ... рдлрд┐рд░ рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВред
props => <Connected...
рдХрд╛ рдЕрдВрддрд┐рдо рдирд┐рд░реНрдорд╛рдг
props => <Connected...
рди рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди, рдмрд▓реНрдХрд┐ рдПрдХ
рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рджреЗрддрд╛ рд╣реИ ред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдм рд╣рдо рдПрдХ рдкреЗрдбрд╝ рдореЗрдВ рдХрдиреЗрдХреНрдЯреЗрдбрд╕реНрдЯреЗрдк 4 рдХреЛ рдПрдореНрдмреЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдЧрд╛:- рдореВрд▓ -> рдЕрдирд╛рдо рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдШрдЯрдХ -> рдХрдиреЗрдХреНрдЯ -> рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рд▓рд┐рд╕реНрдЯрдирд░ -> рдкреНрд░реЛрдорд┐рд╕рдХрдВрдкреЛрдиреЗрдВрдЯ -> рд╕реНрдЯреЗрдк 4
4 рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ, рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпреЗрдХ рдЕрдкрдирд╛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рдПрдХ рдЕрдирд╛рдо рдШрдЯрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рджрд┐рдП рдЧрдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ connect()
, рдиреЗрд╕реНрдЯреЗрдб рдШрдЯрдХ рдХрд╛ рд╡рд░реНрдЧ, рдЧреБрдг рдЬреЛ рдШрдЯрдХ рдХреЛ рддрдм рд╣реА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдЬрдм (рдкреНрд░реЙрдореНрдкреНрд╕) рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдШрдЯрдХ рдХреЛ рдкрд╛рд╕ рдХрд░ рджреЗрддрд╛ рд╣реИ Connect
ред рдШрдЯрдХ Connect
рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ Promise
(рдкрдВрдХреНрддрд┐ рдХреБрдВрдЬрд┐рдпреЛрдВ рдФрд░ рд╡рд╛рджрд╛ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╡рд╕реНрддреБ) рд╕реЗ рдПрдХ рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ ред PromisesComponent
рдореВрд▓реНрдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдХрдиреЗрдХреНрдЯ рдШрдЯрдХ рдореЗрдВ рд╡рд╛рдкрд╕ рднреЗрдЬ рд░рд╣рд╛ рд╣реИ, рдЬреЛ рдореВрд▓ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдЧреБрдгреЛрдВ (рдкреНрд░реЙрдкреНрд╕), рдкрд░рд┐рдХрд▓рд┐рдд рдЧреБрдгреЛрдВ (рдореВрд▓реНрдпреЛрдВ) рдФрд░ рдЧреБрдг-рдХреНрд░рд┐рдпрд╛рдУрдВ (рдХреНрд░рд┐рдпрд╛рдУрдВ) рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдЙрдиреНрд╣реЗрдВ рдШрдЯрдХ Step4
(рдПрдХ рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ React.createElement(...)
) рддрдХ рдкрд╣реБрдВрдЪрд╛рддрд╛ рд╣реИ ред рдЦреИрд░, рдШрдЯрдХRepositoryListener
рдШрдЯрдХ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЕрдЧрд░ рдХреБрдЫ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рддреЛ рдкреНрд░реЙрдорд┐рд╕ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИредрдирддреАрдЬрддрди, рдпрджрд┐ рдХреЛрдИ рднреА рдШрдЯрдХ рдЗрдВрдбреЗрдХреНрд╕рдбрдм рд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЙрд╕рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ рдХрд┐ рд╡рд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝реЗ, connect()
рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдФрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдЧреБрдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмреАрдЪ рдореИрдкрд┐рдВрдЧ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ, рдФрд░ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд┐рд░рджрд░реНрдж рдХреЗ рдХрд░реЗрдВредрдЕрдВрдд рдореЗрдВ, рд╣рдо рдпрд╣ рд╕рдм рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЕрдиреНрдп рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЗрд╕реЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВред рдЗрд╕ рдХрджрдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдерд╛:рдХрд┐рд╕реА рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдмрдЬрд╛рдп: рдХреНрдпрд╛ рдмрдЪрд╛ рд╣реИ
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдФрджреНрдпреЛрдЧрд┐рдХ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реИред рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рд╕реАрдорд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛:- рд╣рдореЗрд╢рд╛ рдмрджрд▓рддреЗ рдЧреБрдгреЛрдВ рд╕реЗ рдирдП рд╡рд╛рджреЗ рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рд╕рдВрд╕реНрдорд░рдг рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдзреНрд╡рдЬ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ IndexedDbRepository рд╕реЗ рд╕реНрдЯрд╛рдореНрдк рдХрд╛рдо рдореЗрдВ рдЖрддрд╛ рд╣реИ (рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХреБрдЫ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреЛрдб рдмреЗрдорд╛рдиреА рд▓рдЧ рд░рд╣рд╛ рдерд╛)ред
- рдЖрдпрд╛рдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднрдВрдбрд╛рд░ рдХреЛ рдЬреЛрдбрд╝рдирд╛, рднрд▓реЗ рд╣реА рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╣реЛ, рдЧрд▓рдд рд╣реИред рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдУрд░ рджреЗрдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
- , IndexedDB .
- : . . IndexDB ┬л┬╗ , тАФ .
- , IndexDB Redux Storage. IndexDB , .
Online-