Π”Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ JavaScript

На ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ JavaScript объяснили, ΠΊΠ°ΠΊ пСрСсСкаСтся Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ, ΠΈ ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π° JS Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎ.

ОблоТка: Π”Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ JavaScript

Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° Π½Π° Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Π½ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π½Π΅ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… ΠΈΠ΄Π΅ΠΉ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅. ΠœΡ‹ постараСмся Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΈΡ… Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΈ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ пСрСсСкаСтся Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² контСкстС JavaScript ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΈ, Ρ‚Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅, Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ программирования Π² ΠΈΡ… чистой Ρ„ΠΎΡ€ΠΌΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π΄Π°Π»Π΅Π΅ Ρ€Π΅Ρ‡ΡŒ ΠΏΠΎΠΉΠ΄Π΅Ρ‚ ΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Ρ… ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°Ρ…, Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½Ρ‹Ρ… для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ стиля программирования.

Π’ ΡΡ‚Π°Ρ‚ΡŒΡΡ…, посвящСнных Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΌΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ, Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΡƒΠΏΠΎΠΌΠΈΠ½Π°ΡŽΡ‚ΡΡ SQL, HTML Π² качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… языков. Π’ Ρ€Π°ΠΌΠΊΠ°Ρ… этих β€œΡΠ·Ρ‹ΠΊΠΎΠ²β€ ΠΌΡ‹ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ„ΠΎΡ€ΠΌΡƒΠ»ΠΈΡ€ΡƒΠ΅ΠΌ ΠΆΠ΅Π»Π°Π΅ΠΌΡ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, вмСсто инструкции ΠΏΠΎ Π΅Π³ΠΎ Π΄ΠΎΡΡ‚ΠΈΠΆΠ΅Π½ΠΈΡŽ, Ρ‡Ρ‚ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ соотвСтствуСт рассматриваСмому ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚Ρƒ. Однако я Ρ…ΠΎΡ‡Ρƒ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΎΠ±Ρ‰ΡƒΡŽ Ρ‡Π΅Ρ€Ρ‚Ρƒ этих Π΄ΠΎΠΌΠ΅Π½Π½Ρ‹Ρ… языков:

Π’ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… языках ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Ρ†ΠΈΠΊΠ»Ρ‹ ΠΈ логичСскиС конструкции.

ΠŸΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° JavaScript с Ρ‚Π°ΠΊΠΈΠΌ тСзисом Π·Π²ΡƒΡ‡ΠΈΡ‚ ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ² ΠΈ Π² ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ стСпСни абсурдно, Π½Π΅ ΠΏΡ€Π°Π²Π΄Π° Π»ΠΈ?

ВспомнитС, ΠΊΠ°ΠΊ часто Π²Π°ΠΌ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² JSX, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚:

			<div>
  {hasComments ? <Comments/> : null}
</div>
		

Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ этот кусочСк ΠΊΠΎΠ΄Π° Π² Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ ΠΌΠ°Π½Π΅Ρ€Π΅:

			<div>
  <Comments visible={hasComments}/>
</div>
		

Как Π±Ρ‹Π»ΠΎ сказано, это Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΊΠΎΠ΄Π°. Π’ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ всС Ρ€Π°Π²Π½ΠΎ упрСмся Π½Π° Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ `if`, Π½ΠΎ ΠΌΡ‹ Π½Π°ΠΌΠ΅Ρ€Π΅Π½Ρ‹ ΠΏΡ€ΡΡ‚Π°Ρ‚ΡŒ Π΅Π³ΠΎ всС дальшС ΠΎΡ‚ основного ΠΊΠΎΠ΄Π°.

			const Comments = ({visible}) => {
  if (!visible) return null
  ...
}
		

НаличиС свойства `visible` Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ΄Ρ‚Π°Π»ΠΊΠΈΠ²Π°Ρ‚ΡŒ нас ΠΊ написанию Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° нСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ сам ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ частично Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² ΠΈΠΌΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΌ стилС.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒ логичСский ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ `switch`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ являСтся Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ блиТайшим родствСнником `if`, Π½ΠΎ ΠΈ Π»ΡŽΠ±ΠΈΠΌΡ‡ΠΈΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΈΡ… Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²:

			const App = () => {
  const role = useUserRole()
  let Component
	switch(role) {
    case 'ADMIN': {
      Component = AdminView
      break
    }
    case 'EDITOR': {
      Component = EditorView
      break
    }
    case 'USER': {
      Component = UserView
      break
    }
    default: {
      Component = GuestView
      break
    }
  }

  return (
    <main>
      <NavBar/>
      <Component/>
    </main>
  )
}
		

НавСрноС Π²Ρ‹ ΡƒΠΆΠ΅ Π΄ΠΎΠ³Π°Π΄Ρ‹Π²Π°Π΅Ρ‚Π΅ΡΡŒ, ΠΊ Ρ‡Π΅ΠΌΡƒ я Π²Π΅Π΄Ρƒ, особСнно учитывая, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΡƒΠΆΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π² React Router.

			const App = () => (
  <main>
    <NavBar/>
    <Switch test={useUserRole()}>
      <Case when='ADMIN' use={AdminView}/>
      <Case when='EDITOR' use={EditorView}/>
      <Case when='USER' use={UserView}/>
      <Otherwise use={GuestView}/>
    </Switch>
  </main>
)
		

Но я Ρ…ΠΎΡ‡Ρƒ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ‚Π΅Π³ΠΈ HTML/JSX Π² Π²ΠΈΠ΄Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ HTML, Π³Π΄Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Ρ‚Π΅Π³Π° ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

			// it will return HTML: <main id="app">Hello World<main/>
main({id: 'app', children: 'Hello world!'})

// The second parameter can be used as a children attribute
main({id: 'app'}, 'Hello world!')
		

ΠžΡΠ½ΠΎΠ²Ρ‹Π²Π°ΡΡΡŒ Π½Π° Π²Ρ‹ΡˆΠ΅ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚ΡƒΡŽ идСю, ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ JSX-ΠΊΠΎΠ΄ Π² Π²ΠΈΠ΄Π΅ Π½Π°Π±ΠΎΡ€ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Π‘Ρ‚ΠΎΠΈΡ‚ ΡƒΡ‡Π΅ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ `switch/case` β€” это Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ слова JavaScript, поэтому ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊ Π½ΠΈΠΌ Π½ΠΈΠΆΠ½ΠΈΠ΅ подчСркивания:

			const app = () => (
  main(
    navbar(),
    switch_({test: useUserRole()},
      case_({when: 'ADMIN', use: AdminView}),
      case_({when: 'EDITOR', use: EditorView}),
      case_({when: 'USER', use: UserView}),
      otherwise({use: GuestView}),
    )
  )
)
		

Как Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ HTML, JSX ΠΈΠ»ΠΈ SQL. Π’ JavaScript ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ синтаксис этих языков с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Если нас ΡƒΡ‡ΠΈΠ»ΠΈ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ собой дСйствия ΠΈ ΠΈΡ… названия Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с Π³Π»Π°Π³ΠΎΠ»Π°, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: `find`, `setTitle`, Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС наши Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ всСгда Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Ρ€Π°ΠΆΠ°Ρ‚ΡŒ дСйствиС ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, SQL-запрос ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Π²ΠΈΠ΄Π΅:

			// a function composition
query(
  select('name', 'email', 'country'),
  from('users'),
  where({age: less(21)}),
  groupBy('country'),
)

// or as a chaining function like Promise
select('name', 'email', 'country')
  .from('users')
  .where({age: less(21)}),
  .groupBy('country')

// Output: 'SELECT name, email, country FROM users WHERE age < 21 GROUP BY country'
		

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ я Ρ…ΠΎΡ‡Ρƒ ΠΏΡ€ΠΎΡ‚ΡΠ½ΡƒΡ‚ΡŒ Π½ΠΈΡ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ.

Π― Π½Π΅ ΡΡ‡ΠΈΡ‚Π°ΡŽ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ прСслСдуСт Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, скорСС это ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΉ эффСкт ΠΎΡ‚ интСнсивного использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

Π’Π°ΠΆΠ½ΠΎ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ это Π½Π΅ просто DRY ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, Π³Π΄Π΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΠΉΡΡ ΠΊΠΎΠ΄ выносится Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π­Ρ‚ΠΎ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠ° написания ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π»Π΅Π³ΠΊΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π² использовании.

ΠŸΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Π΅Ρ‰Π΅ Ρ€Π°Π· Π²Π·Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π½Π° конструкции `switch/case` ΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈΡ… Π² Π²ΠΈΠ΄Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

			const selectComponent = ({test, cases, defaultValue}) => {
  const found = cases.find([value] => test === value)
  return found?.at(1) || defaultValue
}

const App = () => {
  const role = useUserRole()
  const Component = selectComponent({
    test: role,
    cases: [
      ['ADMIN', AdminView],
      ['EDITOR', EditorView],
      ['USER', UserView],
    ],
    defaultValue: GuestView,
  })

  return (
    <main>
      <NavBar/>
      <Component/>
    </main>
  )
}
		

Данная рСализация Π½Π΅ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒΡŽ ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована Π² ΠΊΠΎΠΌΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ функциями. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ `selectComponent` Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π²Ρ‹ΡΡˆΠ΅Π³ΠΎ порядка ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΠ² Π΅Ρ‘ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями, ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ гибкости ΠΈ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

			const select = (...fns) => value => fns.reduce(
  (found, fn) => found || fn(value), null
)

const when = (test, wanted) => value => {
  const matched = typeof test === 'function' ? test(value) : test === value
  return matched && wanted
}

// scalar value
const selectComponent = select(
  when('ADMIN', AdminView),
  when('EDITOR', EditorView),
  when('USER', UserView),
  () => GuestView,
)

const Component = selectComponent('EDITOR') // -> EditorView
		

Если Π²Ρ‹ Π½Π΅ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΠ½ΠΈΠΌΠ°Π»ΠΈ для Ρ‡Π΅Π³ΠΎ Π½ΡƒΠΆΠ½Ρ‹ ΠΊΠ°Ρ€Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ это Ρ…ΠΎΡ€ΠΎΡˆΠ°Ρ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΡ практичСского примСнСния. ΠšΠ°Ρ€Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½Π°Ρ функция прСдставляСт собой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΡƒΡŽ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ, Π½ΠΎ с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ, которая позволяСт ΠΏΡ€ΠΈΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Π΅Ρ‘ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. Π’ΠΎ Π΅ΡΡ‚ΡŒ, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Π΅Ρ‘, пСрСдавая ΠΎΠ΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ откладываСтся Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹. Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ позволяСт ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ дСйствия Π΄ΠΎ фактичСского выполнСния самой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎ позволяСт ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΌ стилС.

Для ясности, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ `selectComponent`, послС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ `when` ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

			const selectComponent = input => [
  value => 'ADMIN' === value ? AdminView : false,
  value => 'EDITOR' === value ? EditorView : false,
  value => 'USER' === value ? UserView : false,
  () => GuestView,
].reduce(
  (found, fn) => found || fn(input), null
)

const Component = selectComponent('ADMIN') // -> AdminView
		

Π“ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ проявляСтся Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ смоТСм ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ мноТСство Π΄Ρ€ΡƒΠ³ΠΈΡ… вСрсий `when`, Π½ΠΎ главная функция `select` Π½Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ. НиТС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π»Π΅Π½ΠΈΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²:

			import {Suspense, lazy} from 'react'

const when = (test, path) => value => (
  test === value && lazy(() => import(path))
)

const selectComponent = select(
  when('ADMIN', './admin-view'),
  when('EDITOR', './editor-view'),
  when('USER', './user-view'),
  () => GuestView,
)

const App = () => {
  const role = useUserRole()
  const Component = selectComponent(role)

  return (
    <main>
      <NavBar/>
      <Suspense fallback={<div>Loading...</div>}>
        <Component/>
      </Suspense>
    </main>
  )
}
		

Если ΠΌΡ‹ вСрнСмся ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠΉ вСрсии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ `selectComponent`, станСт ясно, Ρ‡Ρ‚ΠΎ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Π΅Ρ‘ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» Π±Π΅Π· внСсСния ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π΅ получится. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΌΡ‹ способствуСм Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΡŽ ΠΊΠΎΠ΄Π° Π½Π° ΠΌΠ΅Π»ΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, каТдая ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ, ΠΈ Π² дальнСйшСм ΠΎΠ½ΠΈ ΠΌΠ΅Π½Π΅Π΅ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Ρ‹ измСнСниям.

Когда трСбуСтся Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», ΠΌΡ‹ просто добавляСм Π½ΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΡƒΠ΅ΠΌ Π΅Ρ‘ с ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ, вмСсто Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ.

			const between = (min, max) => n => (
  min >= n && n <= max
)

// range of values
const toGrade = select(
  when(val => val > 88, 'A'),
  when(between(76, 88), 'B'),
  when(between(66, 87), 'C'),
  when(between(55, 65), 'D'),
  () => 'F',
)

const grade = toGrade(78) // -> 'B'
		

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассмотрим Π΄Π°Π½Π½ΡƒΡŽ Ρ‚Π΅Ρ…Π½ΠΈΠΊΡƒ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ создания Ρ€Π΅Π΄ΡŒΡŽΡΠ΅Ρ€ΠΎΠ² Redux. Π£Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ `try/catch` ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌ обсуТдСниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования.

			const authReducer = createReducer(
  initialState,
  on('SIGN_IN', signIn),
  on('SIGN_OUT', signOut),
  on('SIGN_OUT', clearCookies),
)
		
Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ