рд╕реНрд╡рдЪреНрдЫ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП 14 рд╕реБрдЭрд╛рд╡ред рднрд╛рдЧ реи

рдЖрдЬ рд╣рдо рд░рд┐рдПрдХреНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рд╕реНрд╡рдЪреНрдЫ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдкрд░ рд╕рд╛рдордЧреНрд░реА рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдХреБрдЫ рдФрд░ рдЙрдкрдпреЛрдЧреА рд╕реБрдЭрд╛рд╡ рджрд┐рдП рдЧрдП рд╣реИрдВред



тЖТ рдкрд╣рд▓рд╛ рднрд╛рдЧ рдкрдврд╝реЗрдВ

8. рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рддрддреНрд╡реЛрдВ рдХреЛ рдШрдЯрдХреЛрдВ рдореЗрдВ рдмрджрд▓реЗрдВ


рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рддрддреНрд╡реЛрдВ рдХреЛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдШрдЯрдХреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЛ рдРрд╕реЗ рддрддреНрд╡реЛрдВ рдХрд╛ "рдШрдЯрдХрдХрд░рдг" рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреНрд░рддреНрдпреЗрдХ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдЕрдкрдиреЗ рдХрд╛рд░рдг рд╣реИрдВ рдХрд┐ рд╡рд╣ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд░рд┐рдПрдХреНрдЯ рдХреЛрдб рдХреНрдпреЛрдВ рд▓рд┐рдЦрддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдЬрд╛рдирдмреВрдЭрдХрд░ рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрд╛ рдпрд╣ рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЖрд╡реЗрджрди рдореЗрдВ рд╕рдорд╛рди рдХреЛрдб рдЕрдВрд╢реЛрдВ рдХреЗ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдХрд╛ рдХрд╛рд░рдг рдЬреЛ рднреА рд╣реЛ, рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдпрд╣ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╕реЗ рд╕реБрдзрд╛рд░реЗрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдХрд┐рд╕реА рдиреЗ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреА рдЖрджрдд рдирд╣реАрдВ рдмрдирд╛рдИ рд╣реИ, рддреЛ рд╡реЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдмрд╛рд░-рдмрд╛рд░ рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХрд░реЗрдВрдЧреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЯреАрдо рдХрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреМрди рд╕рд╛ рд╣реИ? рдпрд╣ рдмрд╕ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рдЬреАрд╡рди рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдЬреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛрдб рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рдкрд░ рднреНрд░рдорд┐рдд рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рдпрджрд┐ рдЙрдиреНрд╣реЗрдВ рд╕рдорд╛рди рдХреЛрдб рдЕрдВрд╢реЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реИ рддреЛ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ "рдЙрдкрд╣рд╛рд░" рдорд┐рд▓реЗрдЧрд╛ред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдФрд░ рд╕реЛрдЪреЗрдВ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рд╕реБрдзрд╛рд░реЗрдВ:

const SomeComponent = () => (   <Body noBottom>     <Header center>Title</Header>     <Divider />     <Background grey>       <Section height={500}>         <Grid spacing={16} container>           <Grid xs={12} sm={6} item>             <div className={classes.groupsHeader}>               <Header center>Groups</Header>             </div>           </Grid>           <Grid xs={12} sm={6} item>             <div>               <img src={photos.groups} alt="" className={classes.img} />             </div>           </Grid>         </Grid>       </Section>     </Background>     <div>       <Section height={500}>         <Grid spacing={16} container>           <Grid xs={12} sm={6} item>             <div className={classes.labsHeader}>               <Header center>Labs</Header>             </div>           </Grid>           <Grid xs={12} sm={6} item>             <div>               <img src={photos.labs} alt="" className={classes.img} />             </div>           </Grid>         </Grid>       </Section>     </div>   </Body> ) 

рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдм xs={12} sm={6} рд╕реЗ xs={12} sm={4} рд╕реЗ рдЧреНрд░рд┐рдб рдкреИрд░рд╛рдореАрдЯрд░ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдХрд╛рд░реНрдп рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕реБрдЦрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЪрд╛рд░ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдХреЛрдб рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдШрдЯрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рд╕реБрдВрджрд░рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдЙрдкрд░реЛрдХреНрдд рдХреЗ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рдХреЛрдб рдмрджрд▓ рд░рд╣рд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рд╣рд░ рдЬрдЧрд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ рдЬрд╣рд╛рдБ рдЧреНрд░рд┐рдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 const SomeComponent = ({ classes, xs = 12, sm = 6, md, lg }) => {  const BodySection = ({ header, src }) => {    const gridSizes = { xs, sm, md, lg }    return (      <Section height={500}>        <Grid spacing={16} container>          <Grid {...gridSizes} item>            <div className={classes.groupsHeader}>              <Header center>{header}</Header>            </div>          </Grid>          <Grid {...gridSizes} item>            <div>              <img src={src} alt="" className={classes.img} />            </div>          </Grid>        </Grid>      </Section>    )  }  return (    <Body noBottom>      <Header center>Title</Header>      <Divider />      <Background grey>        <BodySection header="Groups" src={photos.groups} />      </Background>      <div>        <BodySection header="Labs" src={photos.labs} />      </div>    </Body>  ) } 

рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдпрд╣рд╛рдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдиреНрдпреВрдирддрдо рд░реВрдкрд╛рдВрддрд░рдг рдХреЛрдб рднреА рдЗрд╕ рдХреЛрдб рдХреЛ рдЙрд╕рдХреЗ рдкрдврд╝рдиреЗ рдФрд░ рд╕рдорд░реНрдерди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рддрд╛ рд╣реИред рд╡рд╣, рдЙрд╕реА рд╕рдордп, рдЙрд╕реЗ рд╕реМрдВрдкреЗ рдЧрдП рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рддрд░реАрдХрд╛ рд╣реИред

9. рдЕрдкрдиреЗ рдШрдЯрдХреЛрдВ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред


рдмрд┐рдХреНрд░реА рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ рдХрднреА-рдХрднреА рдШрдЯрдХ рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рдереА, рд▓реЗрдХрд┐рди рдЙрди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рдирдореЗрдВ рдШрдЯрдХ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ рдПрдХ рдШрдЯрдХ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рдЬрдЯрд┐рд▓ рд╣реИред рдпрд╣ ConfirmAvailability.js рджреНрд╡рд╛рд░рд╛ ConfirmAvailability.js :

 import React from 'react' import Grid from '@material-ui/core/Grid' import Typography from '@material-ui/core/Typography' import MenuItem from '@material-ui/core/MenuItem' import Select from '@material-ui/core/Select' import Time from 'util/time' /** *     .    ,     , ,  ,  * ,    .        .     -     . * * :     Date().getTimezoneOffset().     : *   1.      . *   2.     UTC -     ,   UTC   .  ,       *     UTC. */ export default class TimeZonePicker extends React.Component {  state = {    time: new Date(),    offset: -(new Date().getTimezoneOffset() / 60),  }  componentDidMount() {    this.props.setOffset(this.state.offset)  }  handleChange = (event) => {    const d = new Date()    d.setTime(      d.getTime() +        d.getTimezoneOffset() * 60 * 1000 +        event.target.value * 3600 * 1000,    )    this.setState({      time: d,      offset: event.target.value,    })    this.props.setOffset(event.target.value)  }  render() {    const timezones = []    for (let i = -12; i <= 14; i++) {      timezones.push(        <MenuItem key={i} value={i}>          {i > 0 ? '+' : null}          {i}        </MenuItem>,      )    }    return (      <React.Fragment>        <Grid container justify="space-between">          <div>            <Typography>Current time</Typography>            <Typography variant="h6" gutterBottom>              {Time.formatTime(this.state.time)}            </Typography>          </div>          <div>            <Typography>Set timezone</Typography>            <Select value={this.state.offset} onChange={this.handleChange}>              {timezones}            </Select>          </div>        </Grid>      </React.Fragment>    )  } } 

рдЗрд╕ рдШрдЯрдХ рдХреА рдХрд▓реНрдкрдирд╛ рдПрдХ рд╕рд░рд▓ рддрдВрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХреА рдЧрдИ рдереА, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдЕрддреНрдпрдзрд┐рдХ рд╕рдВрдмрдВрдзрд┐рдд рддрд░реНрдХ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдЬрд┐рд╕ рд╕рдордп рдпрд╣ рдХреЛрдб рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рд░рд┐рдПрдХреНрдЯ рд╣реБрдХ рдЕрднреА рддрдХ рдЬрд╛рд░реА рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рдереЗ, рд▓реЗрдХрд┐рди рд░рд┐рдПрдХреНрдЯ рдореЗрдВ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдХреЗ рдШрдЯрдХ рдФрд░ рд░реЗрдВрдбрд░ рд╕реНрдЯреНрд░рд┐рдкреНрд╕ рдЬреИрд╕реА рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпрд╛рдВ рд╢рд╛рдорд┐рд▓ рдереАрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдШрдЯрдХ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╣рдореЗрдВ рдореМрдЬреВрджрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдШрдЯрдХреЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред

рдкрд╣рд▓реЗ, рд╕рднреА рдХреЛрдб рдПрдХ рд╣реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЧрдП рдереЗред рдЕрдм рд╣рдо рдЗрд╕реЗ рджреЛ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдкрд╣рд▓реА рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рд╣реИ - SelectTimeZone.js :

 import React from 'react' /** *     .    ,     , ,  ,  * ,    .        .     -     . * * :     Date().getTimezoneOffset().     : *   1.      . *   2.     UTC -     ,   UTC   .  ,       *     UTC. */ class SelectTimeZone extends React.Component {  state = {    time: new Date(),    offset: -(new Date().getTimezoneOffset() / 60),  }  componentDidMount() {    this.props.setOffset(this.state.offset)  }  handleChange = (event) => {    const d = new Date()    d.setTime(      d.getTime() +        d.getTimezoneOffset() * 60 * 1000 +        event.target.value * 3600 * 1000,    )    this.setState({      time: d,      offset: event.target.value,    })    this.props.setOffset(event.target.value)  }  getTimeZones = () => {    const timezones = []    for (let i = -12; i <= 14; i++) {      timezones.push(        <MenuItem key={i} value={i}>          {i > 0 ? '+' : null}          {i}        </MenuItem>,      )    }    return timezones  }  render() {    return this.props.render({      ...this.state,      getTimeZones: this.getTimeZones,    })  } } 

рдпрд╣рд╛рдБ рджреВрд╕рд░реА рдлрд╝рд╛рдЗрд▓ рдХреИрд╕реА рджрд┐рдЦрддреА рд╣реИ - TimeZonePicker.js :

 import React from 'react' import Grid from '@material-ui/core/Grid' import Typography from '@material-ui/core/Typography' import MenuItem from '@material-ui/core/MenuItem' import Select from '@material-ui/core/Select' import Time from 'util/time' const TimeZonePicker = () => (  <SelectTimeZone    render={({ time, offset, getTimeZones, handleChange }) => (      <Grid container justify="space-between">        <div>          <Typography>Current time</Typography>          <Typography variant="h6" gutterBottom>            {Time.formatTime(time)}          </Typography>        </div>        <div>          <Typography>Set timezone</Typography>          <Select value={offset} onChange={handleChange}>            {getTimeZones()}          </Select>        </div>      </Grid>    )}  /> ) export default TimeZonePicker 

рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд╛рдж, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛрдб рдкрд╣рд▓реЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╛рдл рд╣реЛ рдЧрдпрд╛ред рд╣рдордиреЗ рдШрдЯрдХ рдХреЗ рдкреНрд░рд╕реНрддреБрддрд┐ рднрд╛рдЧ рд╕реЗ рддрд░реНрдХ рдХреЛ рдирд┐рдХрд╛рд▓рд╛ред рдЕрдм, рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

10. рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЖрдкрдХреЛ рдЬрд┐рддрдиреЗ рдЕрдзрд┐рдХ рд░рд╛рдЬреНрдп рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ, рдЙрддрдиреЗ рд╣реА рдЬрдЯрд┐рд▓ рдЙрдкрдпреЛрдЧ рдХреА useState ред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

 import React from 'react' import axios from 'axios' const useFrogs = () => {  const [fetching, setFetching] = React.useState(false)  const [fetched, setFetched] = React.useState(false)  const [fetchError, setFetchError] = React.useState(null)  const [timedOut, setTimedOut] = React.useState(false)  const [frogs, setFrogs] = React.useState(null)  const [params, setParams] = React.useState({ limit: 50 })  const timedOutRef = React.useRef()  function updateParams(newParams) {    if (newParams != undefined) {      setParams(newParams)    } else {      console.warn(        'You tried to update state.params but the parameters were null or undefined',      )    }  }  function formatFrogs(newFrogs) {    const formattedFrogs = newFrogs.reduce((acc, frog) => {      const { name, age, size, children } = frog      if (!(name in acc)) {        acc[name] = {          age,          size,          children: children.map((child) => ({            name: child.name,            age: child.age,            size: child.size,          })),        }      }      return acc    }, {})    return formattedFrogs  }  function addFrog(name, frog) {    const nextFrogs = {      ...frogs,      [name]: frog,    }    setFrogs(nextFrogs)  }  function removeFrog(name) {    const nextFrogs = { ...frogs }    if (name in nextFrogs) delete nextFrogs[name]    setFrogs(nextFrogs)  }  React.useEffect(() => {    if (frogs === null) {      if (timedOutRef.current) clearTimeout(timedOutRef.current)      setFetching(true)      timedOutRef.current = setTimeout(() => {        setTimedOut(true)      }, 20000)      axios        .get('https://somefrogsaspi.com/api/v1/frogs_list/', { params })        .then((response) => {          if (timedOutRef.current) clearTimeout(timedOutRef.current)          setFetching(false)          setFetched(true)          if (timedOut) setTimedOut(false)          if (fetchError) setFetchError(null)          setFrogs(formatFrogs(response.data))        })        .catch((error) => {          if (timedOutRef.current) clearTimeout(timedOutRef.current)          console.error(error)          setFetching(false)          if (timedOut) setTimedOut(false)          setFetchError(error)        })    }  }, [])  return {    fetching,    fetched,    fetchError,    timedOut,    frogs,    params,    addFrog,    removeFrog,  } } export default useFrogs 

рдпрджрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдпрджрд┐ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ useReducer :

 import React from 'react' import axios from 'axios' const initialFetchState = {  fetching: false  fetched: false  fetchError: null  timedOut: false } const initialState = {  ...initialFetchState,  frogs: null  params: { limit: 50 } } const reducer = (state, action) => {  switch (action.type) {    case 'fetching':      return { ...state, ...initialFetchState, fetching: true }    case 'fetched':      return { ...state, ...initialFetchState, fetched: true, frogs: action.frogs }    case 'fetch-error':      return { ...state, ...initialFetchState, fetchError: action.error }    case 'set-timed-out':      return { ...state, ...initialFetchState, timedOut: true }    case 'set-frogs':      return { ...state, ...initialFetchState, fetched: true, frogs: action.frogs }    case 'add-frog':      return { ...state, frogs: { ...state.frogs, [action.name]: action.frog }}    case 'remove-frog': {      const nextFrogs = { ...state.frogs }      if (action.name in nextFrogs) delete nextFrogs[action.name]      return { ...state, frogs: nextFrogs }    }    case 'set-params':      return { ...state, params: { ...state.params, ...action.params } }      default:        return state  } } const useFrogs = () => {  const [state, dispatch] = React.useReducer(reducer, initialState)  const timedOutRef = React.useRef()  function updateParams(params) {    if (newParams != undefined) {      dispatch({ type: 'set-params', params })    } else {      console.warn(        'You tried to update state.params but the parameters were null or undefined',      )    }  }  function formatFrogs(newFrogs) {    const formattedFrogs = newFrogs.reduce((acc, frog) => {      const { name, age, size, children } = frog      if (!(name in acc)) {        acc[name] = {          age,          size,          children: children.map((child) => ({            name: child.name,            age: child.age,            size: child.size,          })),        }      }      return acc    }, {})    return formattedFrogs  }  function addFrog(name, frog) {    dispatch({ type: 'add-frog', name, frog })  }  function removeFrog(name) {    dispatch({ type: 'remove-frog', name })  }  React.useEffect(() => {    if (frogs === null) {      if (timedOutRef.current) clearTimeout(timedOutRef.current)      timedOutRef.current = setTimeout(() => {        setTimedOut(true)      }, 20000)      axios        .get('https://somefrogsaspi.com/api/v1/frogs_list/', { params })        .then((response) => {          if (timedOutRef.current) clearTimeout(timedOutRef.current)          const frogs = formatFrogs(response.data)          dispatch({ type: 'set-frogs', frogs })        })        .catch((error) => {          if (timedOutRef.current) clearTimeout(timedOutRef.current)          console.error(error)          dispatch({ type: 'fetch-error', error })        })    }  }, [])  return {    fetching,    fetched,    fetchError,    timedOut,    frogs,    params,    addFrog,    removeFrog,  } } export default useFrogs 

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг useState рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╢рд╛рдпрдж рдХреНрд▓реАрдирд░ рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХреЛрдб рдХреЛ рджреЗрдЦрдХрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдирдпрд╛ рдХреЛрдб рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЬрдм useReducer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ useReducer рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рд╣реБрдХ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╣рд┐рд╕реНрд╕реЛрдВ рдореЗрдВ рд░рд╛рдЬреНрдп рдХреЗ рдЕрдкрдбреЗрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рд╕рднреА рдСрдкрд░реЗрд╢рди useReducer рдЕрдВрджрд░ рдПрдХ рд╕реНрдерд╛рди рдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред

рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рддрд░реНрдХ рд▓рд┐рдЦрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд╣реБрдХ рдХреЗ рдЕрдВрджрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рд░рд╛рдЬреНрдп рдХрд╛ рдЕрдЧрд▓рд╛ рд╣рд┐рд╕реНрд╕рд╛ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ useReducer , рдЖрдкрдХреЛ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╕рдм рдХреБрдЫ reducer рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╣рдореЗрдВ рдмрд╕ рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИред

11. рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ


рдЗрд╕ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдПрдХ useEffect рд╕рдлрд╛рдИ useEffect :

 React.useEffect(() => {  setMounted(true)  return () => {    setMounted(false)  } }, []) 

рдПрдХ рдЕрдиреБрднрд╡реА рд░рд┐рдПрдХреНрдЯрд░ рдбреЗрд╡рд▓рдкрд░ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рд▓реМрдЯреЗ рдлрд╝рдВрдХреНрд╢рди рдХреА рднреВрдорд┐рдХрд╛ рдХреНрдпрд╛ рд╣реИ, рд╡рд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рдЗрд╕ рдХреЛрдб рдХреЛ рд╕рдордЭ рдЬрд╛рдПрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдХрд▓реНрдкрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдЬреЛ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕ рдХреЛрдб рдХреЛ рдкрдврд╝реЗрдЧрд╛, рдХреЛрдб рдореЗрдВ рдЕрдкрдиреЗ рдЗрд░рд╛рджреЛрдВ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рд╛рд░реНрдердХ рдирд╛рдо рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдХреЛрдб рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 React.useEffect(() => {  setMounted(true)  return function cleanup() {    setMounted(false)  } }, []) 

рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд▓реМрдЯрд╛рдпрд╛ рдЧрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреНрдпрд╛ рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рддрд╛ рд╣реИред

12. Prettier рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВ


Prettier рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрд╡рд▓рдкрд░реНрд╕ рдФрд░ рдЯреАрдореЛрдВ рдХреЛ рдХреЛрдб рд╕реНрд╡рд░реВрдкрдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд╕рдВрдЧрдд рдФрд░ рд╕реБрд╕рдВрдЧрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдмрдирд╛рдП рд░рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЙрдкрдХрд░рдг рд╕рдордп рдФрд░ рдкреНрд░рдпрд╛рд╕ рдХреЛ рдмрдЪрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреА рд╢реИрд▓реА рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдХреЗ рдХреЛрдб рд╕рдореАрдХреНрд╖рд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИред рдкреНрд░рд┐рдЯрд┐рдпрд░ рд╕реНрд╡рдЪреНрдЫ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЗрдЦрди рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЧреНрд░рд╛рдорд░реЛрдВ рдХреЛ рднреА рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдЙрдкрдХрд░рдг рджреНрд╡рд╛рд░рд╛ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рдирд┐рдпрдо рд╕рдВрдкрд╛рджрди рдпреЛрдЧреНрдп рд╣реИрдВред рдирддреАрдЬрддрди, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рд░ рдХреЛрдИ рдЗрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдлрд┐рдЯ рджреЗрдЦрддреЗ рд╣реИрдВред

13. рдЯреБрдХрдбрд╝рд╛ рдШреЛрд╖рдгрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЖрд╢реБрд▓рд┐рдкрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдареЛрд░


рдЗрд╕ рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХрд╛ рд╕рд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣рд╛рдБ рдЦрдВрдб рдШреЛрд╖рдгрд╛ рдХрд╛ рдЫреЛрдЯрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ:

 const App = () => (  <>    <FrogsTable />    <FrogsGallery />  </> ) 

рдпрд╣рд╛рдБ рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рд╣реИ:

 const App = () => (  <React.Fragment>    <FrogsTable />    <FrogsGallery />  </React.Fragment> ) 

14. рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╕рдордп рддрддреНрд╡реЛрдВ рдХреА рдирд┐рдпреБрдХреНрддрд┐ рдХреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреНрд░рдо рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВред


рдЬрдм рдореИрдВ рдХреЛрдб рд▓рд┐рдЦрддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреНрд░рдо рдореЗрдВ рдХреБрдЫ рдХрдорд╛рдВрдб рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдлрд╝рд╛рдЗрд▓реЗрдВ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╕рдордп рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ (рдпрд╣рд╛рдВ рдЕрдкрд╡рд╛рдж рдХреЗрд╡рд▓ рдЖрдпрд╛рдд react ):

 import React from 'react' import { useSelector } from 'react-redux' import styled from 'styled-components' import FrogsGallery from './FrogsGallery' import FrogsTable from './FrogsTable' import Stations from './Stations' import * as errorHelpers from '../utils/errorHelpers' import * as utils from '../utils/' 

рдЗрд╕ рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдХреЛрдИ рд╕реЛрдЪ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЖрджреЗрд╢ рдирд╣реАрдВ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдЖрдпрд╛рддрд┐рдд рдЗрдХрд╛рдЗрдпрд╛рдВ рднреА рд╡рд░реНрдгрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рдХреНрд░рдордмрджреНрдз рдирд╣реАрдВ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡рд░реНрдгрдорд╛рд▓рд╛ рдХреЗ рдХреНрд░рдо рдореЗрдВ рдХреБрдЫ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдирд╛ рдХреЗрд╡рд▓ рдЖрджреЗрд╢ рджреЗрдиреЗ рд╡рд╛рд▓реА рдпреЛрдЬрдирд╛ рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореИрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

рдореИрдВ, рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рдХреЛрдб рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рдпрдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЬреЛ рд╡реЗ рдЕрдиреБрд╕рд░рдг рдХрд┐рдП рдЧрдП рдХреНрд░рдо рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ:

  1. рдЖрдпрд╛рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ред
  2. рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░реЗрдВ (рд╡рд░реНрдгрдорд╛рд▓рд╛ рдХреНрд░рдо рдореЗрдВ)ред
  3. рдХрд┐рд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреА рдкреВрд░реНрдг рдЖрдЬреНрдЮрд╛ (рд╡рд░реНрдгрдорд╛рд▓рд╛ рдХреЗ рдХреНрд░рдо рдореЗрдВ)ред
  4. рд╕рд╛рдкреЗрдХреНрд╖ рдЖрдпрд╛рдд рдЖрджреЗрд╢ (рд╡рд░реНрдгрдорд╛рд▓рд╛ рдХреНрд░рдо рдореЗрдВ)ред
  5. рдкреНрд░рдкрддреНрд░ import * as ред
  6. рдкреНрд░рдкрддреНрд░ import './<some file>.<some ext>' рдЖрджреЗрд╢ import './<some file>.<some ext>' ред

рдФрд░ рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪрд░ред рдХрд╣реЗрдВ - рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЧреБрдг:

 const character = (function() {  return {    cry() {      //    },    eat() {      //    },    hop() {      //    },    jump() {      //    },    punch() {      //    },    run() {      //    },    scratch() {      //    },    scream() {      //    },    sleep() {      //    },    walk() {      //    },    yawn() {      //    },  } })() 

рдпрджрд┐ рдЖрдк рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╕рдордп рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рдЖрджреЗрд╢ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдирд┐рдпрдореЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВ - рддреЛ рдЗрд╕рдХрд╛ рд╢реБрджреНрдзрддрд╛ рдкрд░ рд▓рд╛рднрдХрд╛рд░реА рдкреНрд░рднрд╛рд╡ рдкрдбрд╝реЗрдЧрд╛ред

рдкрд░рд┐рдгрд╛рдо


рд╣рдордиреЗ рдЖрдкрдХреЛ рд╕реНрд╡рдЪреНрдЫ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдпреБрдХреНрддрд┐рдпрд╛рдВ рдкреНрд░рджрд╛рди рдХреА рд╣реИрдВред рд╣рдо рдЖрд╢рд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдЙрдирдХреЗ рдмреАрдЪ рдХреБрдЫ рдРрд╕рд╛ рдкрд╛рдПрдВрдЧреЗ рдЬреЛ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред

рдкреНрд░рд┐рдп рдкрд╛рдардХреЛрдВ! рдЗрд╕ рдЖрд▓реЗрдЦ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рд╕реБрдЭрд╛рд╡реЛрдВ рдореЗрдВ рдЖрдк рдХреНрдпрд╛ рд╕рд┐рдлрд╛рд░рд┐рд╢реЗрдВ рдЬреЛрдбрд╝реЗрдВрдЧреЗ?

Source: https://habr.com/ru/post/hi465813/


All Articles