рдХреЛрдЯрд▓рд┐рди + рд░рд┐рдПрдХреНрдЯ рдмрдирд╛рдо рдЬрд╡рд╛рд╕рдЯреНрд░рд┐рдк + рд░рд┐рдПрдХреНрдЯ

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

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо Kotlin + React рдкрд░ рдЕрдкрдиреЗ рд╕рдордХрдХреНрд╖ рдХреЗ рд╕рд╛рде Javasript + React рдкрд░ рдПрдХ рдкреЗрдЬ рд▓рд┐рдЦреЗрдВрдЧреЗред рддреБрд▓рдирд╛ рдХреЛ рдИрдорд╛рдирджрд╛рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЬреЛрдбрд╝реАред



рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЬреЛрдбрд╝рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рдерд╛ред рдпрджрд┐ рдХреЛрдЯрд▓рд┐рди рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдврд╛рд▓, рдПрдирдкреАрдПрдо рдФрд░ рд╡реЗрдмрдкреИрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдкреНрд░реАрд╕реЗрдЯ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛, рдкреНрд░рд╡рд╛рд╣, es2015 рдФрд░ рдЪрд░рдг -2 рдХреЗ рд╕рд╛рде npm, webpack, flow рдФрд░ babel рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рдпрд╣рд╛рдВ рдкреНрд░рд╡рд╛рд╣ рдХрд┐рд╕реА рддрд░рд╣ рдкрдХреНрд╖ рдореЗрдВ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ рдЖрдИрдбреАрдИ рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд┐рддреНрд░ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рдЕрд╕реЗрдВрдмрд▓реА рдФрд░ рд▓рд╛рдЗрдХ рдХреЛ рдмреНрд░реИрдХреЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЛрдб рд░рд╛рдЗрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП, рдПрдХ рдУрд░ рдХреЛрдЯрд▓рд┐рди + рд░рд┐рдПрдХреНрдЯ рд░рд╣рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░реА рдкрд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ + рд░рд┐рдПрдХреНрдЯ + рдмреИрдмрд▓ + рдлреНрд▓реЛ + ES5 | ES6 | ES7 |

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

рдкрд░рд┐рдгрд╛рдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ (рдореИрдВ рдбрд┐рдЬрд╛рдЗрдирд░ рдирд╣реАрдВ рд╣реВрдВ):



рдореИрдВ рдпрд╣рд╛рдВ рдЗрд╕ рд╕рдВрдкреВрд░реНрдг рд╢реИрддрд╛рдиреА рдорд╢реАрди рдХреЗ рд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдпрд╣ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╖рдп рд╣реИ (рдЕрдм рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕ рдПрдХ рд╕реЗ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдзреВрдореНрд░рдкрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред

рдкреАрдЫреЗ рд╕реЗ рдбреЗрдЯрд╛ рд▓реЛрдб рд╣реЛ рд░рд╣рд╛ рд╣реИ


рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдкреАрдЫреЗ рд╕реЗ рдмреНрд░рд╛рдВрдбреЛрдВ рдФрд░ рдЙрдкрд▓рдмреНрдз рд░рдВрдЧреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ
kotlin
class Home extends React.Component <ContextRouter, State>{ state = { loaded: false, //(1) color: queryAsMap( this.props.location.search )["color"], brand: queryAsMap( this.props.location.search )["brand"], brands: [], //(2) colors: [] //(2) }; async componentDidMount() { this.setState({ //(3) brands: await ( //(4) await fetch('/api/brands') ).json(), colors: await ( //(4) await fetch('/api/colors') ).json() }); } } type State = { color?: string, //(5) brand?: string, //(5) loaded: boolean, //(1) brands: Array<string>, //(2) colors: Array<string> //(2) }; export default Home; 

 class Home( props: RouteResultProps<*> ) : RComponent <RouteResultProps<*>, State> (props) { init { state = State( color = queryAsMap( props.location.search )["color"], brand = queryAsMap( props.location.search )["brand"] ) } override fun componentDidMount() { launch { updateState { //(3) brands = fetchJson( //(4) "/api/brands", StringSerializer.list ) colors = fetchJson( //(4) "/api/colors", StringSerializer.list ) } } } } class State( var color: String?, //(5) var brand: String? //(5) ) : RState { var loaded: Boolean = false //(1) lateinit var brands: List<String> //(2) lateinit var colors: List<String> //(2) } private val serializer: JSON = JSON() suspend fun <T> fetchJson( //(4) url: String, kSerializer: KSerializer<T> ): T { val json = window.fetch(url) .await().text().await() return serializer.parse( kSerializer, json ) } 


рдпрд╣ рдмрд╣реБрдд рд╕рдорд╛рди рджрд┐рдЦрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдорддрднреЗрдж рд╣реИрдВ:

  1. рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдЙрд╕реА рд╕реНрдерд╛рди рдкрд░ рд▓рд┐рдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдкреНрд░рдХрд╛рд░ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдХреЛрдб рдХреА рдЕрдЦрдВрдбрддрд╛ рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
  2. рд▓реЗрдЯрдЗрдирд┐рдЯ рдЖрдкрдХреЛ рдмрд╛рдж рдореЗрдВ рдЬреЛ рд▓реЛрдб рд╣реЛрдЧрд╛ рдЙрд╕рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИред рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди, рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЪрд░ рдХреЛ NotNull рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рд░ рдмрд╛рд░ рдЬрдм рдЗрд╕реЗ рдЪреЗрдХ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдорд╛рдирд╡-рдкрдардиреАрдп рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИред рдпрд╣ рдПрдХ рд╕рд░рдгреА рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдЪ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕рд╛рде рд╣реА рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрддрдирд╛ рдмреЛрдЭрд┐рд▓ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХреАред
  3. рдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рдХреЛрдЯрд▓рд┐рди-рд░рд┐рдПрдХреНрд╢рди рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдлрдВрдХреНрд╢рди рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЗрдирд▓рд╛рдЗрди рдирд╣реАрдВ рд╣реИред рдореБрдЭреЗ рдЗрдирд▓рд╛рдЗрди рдХреЛ рдХреЙрдкреА рдХрд░рдХреЗ рд░рдЦрдирд╛ рдерд╛ред
  4. рджрд░рдЕрд╕рд▓, рдХреЙрд░рдЖрдЙрдЯ ред рдпрд╣ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрдкрдЬ рдЙрдирдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИред рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдореЗрдВ рдХреЗрд╡рд▓ рд╕рд╕реНрдкреЗрдВрдб рд╢рдмреНрдж рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ, рдмрд╛рдХреА рд╕рдм рд╕рд┐рд░реНрдл рдХреЛрдб рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЙрдкрдпреЛрдЧ рдХреА рдЕрдзрд┐рдХ рд╕реНрд╡рддрдВрддреНрд░рддрд╛ред рдФрд░ рд╕рдВрдХрд▓рди рд╕реНрддрд░ рдкрд░ рдереЛрдбрд╝рд╛ рддрдВрдЧ рдирд┐рдпрдВрддреНрд░рдгред рдЗрд╕рд▓рд┐рдП, рдЖрдк рдШрдЯрдХ рдХреЛ suspend рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВрдбрд┐рдорд╛рдЙрдВрдЯ рдПрдХ suspend рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде, рдЬреЛ рдХрд┐ рддрд╛рд░реНрдХрд┐рдХ рд╣реИ: рдШрдЯрдХрдбреАрдбрдорд╛рдЙрдВрдЯ рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╡рд┐рдзрд┐ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдк рдХреЛрдб рдореЗрдВ рдХрд╣реАрдВ рднреА launch { } рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмреНрд▓реЙрдХ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рд╡рд░реНрдЧ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╛ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ (рдмрд╕ рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ)ред
  5. рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдХрдо рдирд┐рдпрдВрддреНрд░рдг рдЕрд╢рдХреНрдд рд╣реИред рдЗрд╕рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдореА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдк рдмреНрд░рд╛рдВрдб, рд░рдВрдЧ рдФрд░ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдб рдХреА рдЕрд╢рдХреНрддрддрд╛ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдм рдХреБрдЫ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХреЛрдЯрд▓рд┐рди рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЙрдЪрд┐рдд рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреАред

рдХреЛрд░реБрдЯрд┐рди рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирд╛рдВрддрд░ рдЯреНрд░реЗрдХрд┐рдВрдЧ
 suspend fun parallel(vararg tasks: suspend () -> Unit) { tasks.map { async { it.invoke() } //  task,    . async {}  -  promise }.forEach { it.await() } // ,   } override fun componentDidMount() { launch { updateState { parallel({ halls = hallExchanger.all() }, { instructors = instructorExchanger.active() }, { groups = fetchGroups() }) } } } 


рдЕрдм рдХреНрд╡реЗрд░реА рд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╢реАрдиреЛрдВ рдХреЛ рдкреАрдЫреЗ рд╕реЗ рд▓реЛрдб рдХрд░реЗрдВ
рдЬреЗ рдПрд╕:

  async loadCars() { let url = `/api/cars?brand=${this.state.brand || ""}&color=${this.state.color || ""}`; this.setState({ cars: await (await fetch(url)).json(), loaded: true }); } 

Kotlin:

  private suspend fun loadCars() { val url = "/api/cars?brand=${state.brand.orEmpty()}&color=${state.color.orEmpty()}" updateState { cars = fetchJson(url, Car::class.serializer().list) //(*) loaded = true } } 

рдореИрдВ Car::class.serializer().list рдзреНрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЬреЗрдЯрдмреНрд░рд╛рдЗрдиреНрд╕ рдиреЗ рдХреНрд░рдорд╛рдВрдХрди / рдбреАрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд▓рд┐рдЦрд╛ рд╣реИ рдЬреЛ рдЬреЗрд╡реАрдПрдо рдФрд░ рдЬреЗрдПрд╕ рдкрд░ рд╕рдорд╛рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдХрдо рд╕рдорд╕реНрдпрд╛рдУрдВ рдФрд░ рдХреЛрдб рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдмреИрдХрдПрдВрдб рдЬреЗрд╡реАрдПрдо рдкрд░ рд╣реИред рджреВрд╕рд░реЗ, рдЖрдиреЗ рд╡рд╛рд▓реЗ рдЬрд╕рди рдХреА рд╡реИрдзрддрд╛ рдХреЛ рдбреАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ, рди рдХрд┐ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП, рдЗрд╕рд▓рд┐рдП рдмреИрдХ-рдПрдВрдб рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдмрджрд▓рддреЗ рд╕рдордп, рдФрд░ рдЬрдм рд╕рд┐рджреНрдзрд╛рдВрдд рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЕрдзрд┐рдХ рддреЗрдЬрд╝ рд╣реЛрдВрдЧреАред

рд╣рдо рдлрд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЯреЛрдкреА рдЦреАрдВрдЪрддреЗ рд╣реИрдВ


рд╣рдо рджреЛ рдбреНрд░реЙрдк-рдбрд╛рдЙрди рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдШрдЯрдХ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдХреЛрдЯрд▓рд┐рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реЛрдЧрд╛, рдЬреЗрдПрд╕ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдШрдЯрдХ рд╣реИ рдЬреЛ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЗ рджреМрд░рд╛рди рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд▓реЛрдбрд░ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ
kotlin
 type HomeHeaderProps = { brands: Array<string>, brand?: string, onBrandChange: (string) => void, colors: Array<string>, color?: string, onColorChange: (string) => void } const HomeHeader = ({ brands, brand, onBrandChange, colors, color, onColorChange }: HomeHeaderProps) => ( <div> Brand: <Dropdown value={brand} onChange={e => onBrandChange(e.value) } options={withDefault("all", brands.map(value => ({ label: value, value: value })))} /> Color: <Dropdown value={color} onChange={e => onColorChange(e.value) } options={withDefault("all", colors.map(value => ({ label: value, value: value })))} /> </div> ); function withDefault( label, options ) { options.unshift({ label: label, value: null }); return options; } 

 private fun RBuilder.homeHeader( brands: List<String>, brand: String?, onBrandChange: (String?) -> Unit, colors: List<String>, color: String?, onColorChange: (String?) -> Unit ) { +"Brand:" dropdown( value = brand, onChange = onBrandChange, options = brands.map { SelectItem( label = it, value = it ) } withDefault "all" ) {} +"Color:" dropdown( value = color, onChange = onColorChange, options = colors.map { SelectItem( label = it, value = it ) } withDefault "all" ) {} } infix fun <T : Any> List<SelectItem<T>>.withDefault( label: String ) = listOf( SelectItem( label = label, value = null ) ) + this 


рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рдЖрдкрдХреА рдЖрдВрдЦ рдХреЛ рдкрдХрдбрд╝рддреА рд╣реИ - рдЬреЗрдПрд╕ рднрд╛рдЧ рдореЗрдВ рд╣реЛрдорд╣реЗрдбрд░рдкреНрд░реЙрдкреНрд╕, рд╣рдо рдЖрдиреЗ рд╡рд╛рд▓реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реИрдВред рдЕрд╕рд╣рдЬред

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

рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдбреНрд░реЙрдкрдбрд╛рдЙрди рдХреЗ рд▓рд┐рдП рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╕рдВрд╢реНрд▓рд┐рд╖реНрдЯ рдЪреАрдиреАред })))} js рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред рд▓реЗрдХрд┐рди рд╢рдмреНрджреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рд╕реАрдзрд╛ рдХрд░рдирд╛ рдХрд╣реАрдВ рдЕрдзрд┐рдХ рд╕реБрдЦрдж рд╣реИ: "рд╣рдо рд░рдВрдЧреЛрдВ рдХреЛ рдЖрдЗрдЯрдо рдореЗрдВ рдмрджрд▓ рджреЗрдВрдЧреЗ рдФрд░ 'рд╕рднреА рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ", рдЗрд╕рдХреЗ рдмрдЬрд╛рдп "рд╕рднреА рдХреЛ рдЖрдЗрдЯрдо рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рдВрдЧреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ"ред рдпрд╣ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдмреЛрдирд╕ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдХрдИ рдРрд╕реЗ рдХреВрдк рд╣реЛрддреЗ рд╣реИрдВ ...

рд╣рдо рдХреНрд╡реЗрд░реА рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ


рдЕрдм рдЬрдм рдмреНрд░рд╛рдВрдб рдФрд░ рд░рдВрдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдлрд┐рд▓реНрдЯрд░ рдЪреБрдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд░рд╛рдЬреНрдп рдХреЛ рдмрджрд▓рдиреЗ, рдкреАрдЫреЗ рд╕реЗ рдХрд╛рд░реЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдпреВрдЖрд░рдПрд▓ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ
kotlin
 render() { if (!this.state.loaded) return null; return ( <HomeHeader brands={this.state.brands} brand={this.state.brand} onBrandChange={brand => this.navigateToChanged({brand})} colors={this.state.colors} color={this.state.color} onColorChange={color => this.navigateToChanged({color})} /> ); } navigateToChanged({ brand = this.state.brand, color = this.state.color }: Object) { //(*) this.props.history.push( `?brand=${brand || ""}` + `&color=${color || ""}`); this.setState({ brand, color }); this.loadCars() } 

  override fun RBuilder.render() { if (!state.loaded) return homeHeader( brands = state.brands, brand = state.brand, onBrandChange = { navigateToChanged(brand = it) }, colors = state.colors, color = state.color, onColorChange = { navigateToChanged(color = it) } ) } private fun navigateToChanged( brand: String? = state.brand, color: String? = state.color ) { props.history.push( "?brand=${brand.orEmpty()}" + "&color=${color.orEmpty()}") updateState { this.brand = brand this.color = color } launch { loadCars() } } 


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

рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдВ


рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рд╡рд╣ рдорд╢реАрдиреЛрдВ рдХреЗ рд╕рд╛рде рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдШрдЯрдХ рд╣реИред

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ
kotlin
 const HomeContent = (props: { cars: Array<Car> }) => ( <DataTable value={props.cars}> <Column header="Brand" body={rowData => rowData["brand"] }/> <Column header="Color" body={rowData => <span style={{ color: rowData['color'] }}> {rowData['color']} </span> }/> <Column header="Year" body={rowData => rowData["year"]} /> </DataTable> ); 

 private fun RBuilder.homeContent( cars: List<Car> ) { datatable(cars) { column(header = "Brand") { +it.brand } column(header = "Color") { span { attrs.style = js { color = it.color } +it.color } } column(header = "Year") { +"${it.year}" } } } 


рдпрд╣рд╛рдБ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВрдиреЗ рдХреИрд╕реЗ рдПрдлрд╝реА рдкреНрд░рд╛рдЗрдордлреЗрд╕ рдХреЛ рд╕реАрдзрд╛ рдХрд┐рдпрд╛ рдФрд░ рдХреЛрдЯрд▓рд┐рди-рд░рд┐рдПрдХреНрд╢рди рдореЗрдВ рдХреИрд╕реЗ рд╕реНрдЯрд╛рдЗрд▓ рдХрд┐рдпрд╛ред рдпрд╣ рдирд┐рдпрдорд┐рдд json рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ js рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╣реИред рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ, рдореИрдВрдиреЗ рдПрдХ рд░реИрдкрд░ рдмрдирд╛рдпрд╛ рдЬреЛ рд╕рдорд╛рди рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдордЬрдмреВрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рд╕рд╛рде, html рд╕реНрдЯрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗред

рдирд┐рд╖реНрдХрд░реНрд╖


рдирдИ рддрдХрдиреАрдХ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЬреЛрдЦрд┐рдо рднрд░рд╛ рд╣реИред рдХреБрдЫ рдЧрд╛рдЗрдб рд╣реИрдВ, рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдкрд░ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рдХреБрдЫ рдмреБрдирд┐рдпрд╛рджреА рдЪреАрдЬреЗрдВ рдЧрд╛рдпрдм рд╣реИрдВред рд▓реЗрдХрд┐рди рдХреЛрдЯрд▓рд┐рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЗрд░реА рд▓рд╛рдЧрддреЛрдВ рдХрд╛ рднреБрдЧрддрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдЬрдм рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рддреИрдпрд╛рд░ рдХрд░ рд░рд╣рд╛ рдерд╛, рдореИрдВрдиреЗ рдЖрдзреБрдирд┐рдХ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирдИ рдЪреАрдЬреЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╕реАрдЦрд╛: рдкреНрд░рд╡рд╛рд╣, рдмреИрдмреЗрд▓, рдПрд╕рд┐рдХреНрд╕ / рд╡реЗрдЯ, рдЬреЗрдПрд╕рдПрдХреНрд╕ рдЯреЗрдореНрдкреНрд▓реЗрдЯред рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдпрд╣ рдЬреНрдЮрд╛рди рдХрд┐рддрдиреА рдЬрд▓реНрджреА рдЕрдкреНрд░рдЪрд▓рд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ? рдФрд░ рдпрд╣ рд╕рдм рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдЖрдк рдХреЛрдЯрд▓рд┐рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕реА рд╕рдордп, рдЖрдкрдХреЛ рд░рд┐рдПрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рд╕рдорд╕реНрдпрд╛рдПрдВ рднрд╛рд╖рд╛ рдХреА рдорджрдж рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рд╣рд▓ рд╣реЛ рдЬрд╛рддреА рд╣реИрдВред

рдФрд░ рдХреНрдпрд╛ рдЖрдк рдЗрд╕ рд╕рднреА рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рдХреЛ рдПрдХ рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдмрдиреНрд╕ рдХреЗ рдмрдбрд╝реЗ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрддреЗ рд╣реИрдВ?

рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рд╕реНрд░реЛрдд рдХреЛрдб ред

рдкреБрдирд╢реНрдЪ: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХреА рдпреЛрдЬрдирд╛, JVM рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдФрд░ dsl рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рдбреЛрдо рдФрд░ рдирд┐рдпрдорд┐рдд html рджреЛрдиреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдгред

рдХреЛрдЯрд▓рд┐рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦреЗ рдЧрдП рд▓реЗрдЦ:

рдХреЛрдЯрд▓рд┐рди рд╕реЗ рдЖрдлреНрдЯрд░рд╕реНрдЯ, рднрд╛рдЧ 1
рдХреЛрдЯрд▓рд┐рди рдХреЗ рдмрд╛рдж рдХрд╛ рднрд╛рдЧ, 2
рдХреЛрдЯрд▓рд┐рди рдХреЗ рдмрд╛рдж рдХрд╛ рднрд╛рдЧ, 3. рдХреЛрд░рдЯрд╛рдЗрди - рд╢реЗрдпрд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рдордп

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


All Articles