2020년 구성 요소 조작 및 사용 9가지 방법

medium에서 나를 찾았다
혁신이 끊임없이 나타나면서 특히 자바스크립트 커뮤니티에서는 웹 개발자가 될 수 있는 좋은 시기입니다!React는 복잡한 사용자 인터페이스를 구축하는 믿을 수 없는 라이브러리이다. 만약 당신이 초보자라면 본고는 웹 개발자가 당신의 지배 아래 그것을 얼마나 강력하게 사용하는지 이해하는 데 도움을 줄 수 있다.만약react에 대해 낯설지 않다면, 이 글에서 새로운 것을 찾을 수 없을 수도 있지만, 이 글에서 새로운 것을 찾을 수 있기를 바랍니다. 왜냐하면 나는react 구성 요소를 사용하는 새로운 정책을 공개하려고 하기 때문입니다.
이 글에서는 2020년 리액트 구성 요소를 조작하고 사용하는 9가지 방법에 대해 논의할 예정이다.
더 이상 귀찮게 할 필요 없어, 우리 시작하자!

1. 어셈블리 지지


기존 구성 요소를 논리로 다시 사용하고 다른 곳으로 전달하는 여러 가지 방법 중 하나는 도구를 통해 논리를 사용자 정의 구성 요소로 전달하는 방법을 제공하는 것이다.
Material-UI처럼 유행하는react 구성 요소 라이브러리는 거의 모든 구성 요소에서 이런 정책을 자주 사용합니다.
왜 이것이 논리를 중용하는 좋은 방법인지 설명할 충분한 이유가 있다.
예를 원한다면 PrivateRoute 프로그램의 Gatsby 구성 요소를 보십시오.그것은 인증 논리를 봉인하는 간단한 구성 요소이다.현재 사용자가 인증을 통과하지 못하면 로그인 화면으로 다시 지정됩니다.그렇지 않으면, props.component 에서 받은 구성 요소를 계속 보여 줍니다.props.component에서 전달된 모든 내용을 보여 주기 때문에 임의의 여러 구성 요소에 이 인증 논리를 반복해서 사용할 수 있습니다.그것은 그것을 루트 논리를 처리하는 간단하고 강력한 방법으로 만들었다.
또한 HTMLDOM 요소를 나타내는 문자열을 전달할 수 있습니다. 예를 들어 "div""span" 등은 reactinternally calls React.createElement에서 요소type로 전달하기 때문에 구성 요소로 전달됩니다.

2. 원소, 클래스 구성 요소 또는 함수 구성 요소를 한 번에 호출합니다


React 개발팀은 사용자 인터페이스의 모양을 설명할 때 JSX를 사용하는 것을 권장합니다.
그러나 JSX를 사용하는 것은 최종적으로React.createElement의 문법사탕만 호출하는 것임을 잊지 말아야 한다.따라서, 특히, 당신도 안전하게 React.createElement로 구성 요소를 만들 수 있습니다.
JSX에 비해 사용React.createElement이 좋다.
내가 가장 흥미를 느끼는 장점 중 하나는 일반적인 자바스크립트를 다시 쓰기 시작하는 것이다. 왜냐하면 우리는 현재 함수만 사용하기 때문이다.다른 장점은 이 호출을 react에서 처리하지 않고, 하나의 코드 블록에서 모든 세부 사항에 접근하는 것을 포함하기 때문에 자바스크립트가 실행해야 하는 추가 절차를 피할 수 있습니다.
react final formmakes extensive use of this pattern 뒤에 있는 팀은 공장으로서 그들의 현장 구성 요소를 만든다.

3. 고급 구성 요소 납치 도구(HOC)


React에서 고급 구성 요소는 구성 요소의 논리를 다시 사용하는 고급 기술로서 과거에는 상당히 큰 영광을 누렸다.그러나 상황은 여전히 이렇다.그것들은 기본적으로react 구성 요소를 매개 변수로 하고 새로운 구성 요소를 되돌려주는 함수입니다.
이런 방법을 사용하면 '보이지 않는' 중간층에서 구성 요소의 도구를 덮어쓰고 납치할 수 있다.이'중간층'은 고급 구성 요소 논리가 발생하는 곳이다.그들은 포장 구성 요소를 덮어쓰는 도구를 선택하거나 렌더링 행위를 제어할 수 있습니다.
이를 증명하기 위해, 나는 기본적인 withAuthValidation 고급 구성 요소를 작성했는데, 이것은 관리자 사용자에게만 사용할 수 있는 입력 DeactivatorInput 을 전달할 것이다.먼저 하나의 구성 요소를 도구로 삼아 인증 논리를 실행합니다. 사용자가 인증을 하지 않으면 입력을 사용하지 않으려고 시도합니다.
import React from 'react'

function isAuthed(token) {
  // some auth logic
}

const withAuthValidation = (WrappedComponent) => {
  return (props) => {
    if (isAuthed(props.token)) {
      return <WrappedComponent {...props} />
    }
    return <WrappedComponent {...props} disabled />
  }
}

const DeactivatorInput = ({ style, ...rest }) => (
  <input
    {...rest}
    style={{
      minWidth: 200,
      border: '1px solid rgba(0, 0, 0, 0.5)',
      borderRadius: 4,
      padding: '6px 12px',
      ...style,
    }}
    placeholder="Search a user to deactivate"
  />
)

// Applies the higher order component. This is the component we use to render
//    in place of DeactivatorInput
const DeactivatorInputWithAuthValidation = withAuthValidation(DeactivatorInput)

function App() {
  return (
    <div>
      <DeactivatorInputWithAuthValidation />
    </div>
  )
}

export default App

4. 렌더링 도구를 사용하여 구성 요소 논리 재사용


나는 render props were first being brought to the surface 당시 리액션 커뮤니티에서 빠르게 유행하기 시작했고 구성 요소에서 코드 논리를 다시 사용하는 데 사용되는 광범위한 모델이 된 것을 기억한다.
이런 모델을 사용하면 고급 구성 요소가 해결하려고 하는 문제를 해결할 수 있다.그러나 많은 개발자들이renderprop 모드를 사용하는 것을 좋아한다. 이것은 좋은 이유가 있다. 고급 구성 요소가 필요한 곳에 문제를 도입했기 때문이다copy over static methods.
렌더링 도구가 많은 사람들의 사랑을 받는 또 다른 좋은 이유는 고급 구성 요소를 사용하는 것처럼 새로운 구성 요소의 실례를 실례화하지 않았기 때문이다.모드를 수행하려면 하나의 구성 요소만 사용하십시오. (이것은 당신에게 더욱 로컬한 반응을 줄 것입니다.)
function AuthValidator({ token, render, ...rest }) {
  if (isAuthed(token)) {
    return render({ authenticated: true })
  }
  return render({ authenticated: false })
}

const DeactivatorInput = ({ style, ...rest }) => (
  <input
    {...rest}
    style={{
      minWidth: 200,
      border: '1px solid rgba(0, 0, 0, 0.5)',
      borderRadius: 4,
      padding: '6px 12px',
      ...style,
    }}
    placeholder="Search a user to deactivate"
  />
)

function App() {
  return (
    <div>
      <AuthValidator
        token="abc123"
        render={({ authenticated }) => (
          <DeactivatorInput disabled={!authenticated} />
        )}
      />
    </div>
  )
}

5. 서브어셈블리 논리를 함수로 재사용


이것은 렌더링 속성을 사용하는 방법과 기본적으로 같습니다. 다만 보기에는 다릅니다. react에서 하위 항목을 시작 구성 요소 표시와 끝 표시 사이에 두었기 때문에 논리적으로는 거기에 남을 것입니다.
function AuthValidator({ token, children, ...rest }) {
  if (isAuthed(token)) {
    return children({ authenticated: true })
  }
  return children({ authenticated: false })
}

const DeactivatorInput = ({ style, ...rest }) => (
  <input
    {...rest}
    style={{
      minWidth: 200,
      border: '1px solid rgba(0, 0, 0, 0.5)',
      borderRadius: 4,
      padding: '6px 12px',
      ...style,
    }}
    placeholder="Search a user to deactivate"
  />
)

function App() {
  return (
    <div>
      <AuthValidator token="abc123">
        {({ authenticated }) => <DeactivatorInput disabled={!authenticated} />}
      </AuthValidator>
    </div>
  )
}

6. 여러 렌더링 기능을 사용하여 구성 요소 논리 재사용


렌더링/하위 함수 하나에 그치지 않고
import React from 'react'
import Topbar from './Topbar'
import Sidebar from './Sidebar'
import About from './About'
import Contact from './Contact'
import PrivacyPolicy from './PrivacyPolicy'
import Dashboard from './Dashboard'
import { Router } from '@reach/router'

function App() {
  return (
    <Router>
      <Dashboard
        topbar={({ authenticated }) => (
          <Router>
            <Topbar path="*" authenticated={authenticated} />
          </Router>
        )}
        sidebar={() => (
          <Router>
            <Sidebar path="*" />
          </Router>
        )}
        view={({ authenticated }) => (
          <Router>
            <About path="/about" />
            <Contact path="/contact" />
            <PrivacyPolicy path="/privacy-policy" />
            <Admin path="/admin" authenticated={authenticated} />
          </Router>
        )}
      />
    </Router>
  )
}

export default App
그러나 나는 이런 방법을 좋아하지 않고 추천하지 않는다. 왜냐하면 Dashboard의 렌더링 방법을 작성할 때 이런 방법은 매우 제한적일 수 있기 때문이다.그러나 위와 같은 경우에는 사이드바 또는 위쪽 표시줄이 UI의 다른 위치에서 이동하지 않으므로 유용할 수 있습니다.

7.React 갈고리를 사용하여 어셈블리 로직 재사용


그 후react hooks 이 폭풍이 지역 사회를 오늘까지 휩쓸었다.
갈고리를 사용하면 위에 나열된 모든 문제를 해결하고 함수로 느껴지는 것을 사용하여 JavaScript로 돌아갈 수 있습니다.
import React from 'react'

function useStuff() {
  const [data, setData] = React.useState({})

  React.useEffect(() => {
    fetch('https://someapi.com/api/users/')
      .then((response) => setData(response.json()))
      .catch((err) => setData(err))
  }, [])

  return { data, setData }
}

function App() {
  const { data } = useStuff()

  if (data instanceof Error) {
    return <p style={{ color: 'red' }}>Error: {data.message}</p>
  }

  return <div>{JSON.stringify(data, null, 2)}</div>
}
렌더링 도구가 다른 도구 컴포넌트에 중첩된 여러 렌더링 도구 컴포넌트를 렌더링할 때 다음과 같은 "콜백 지옥"을 만나게 됩니다.
import React from 'react'
import ControlPanel from './ControlPanel'
import ControlButton from './ControlButton'

function AuthValidator({ token, render, ...rest }) {
  if (isAuthed(token)) {
    return render({ authenticated: true })
  }
  return render({ authenticated: false })
}

function App() {
  return (
    <div>
      <AuthValidator
        render={({ authenticated }) => {
          if (!authenticated) {
            return null
          }
          return (
            <ControlPanel
              authenticated={authenticated}
              render={({ Container, controls }) => (
                <Container
                  render={({ width, height }) => (
                    <div style={{ width, height }}>
                      {controls.map((options) =>
                        options.render ? (
                          <ControlButton
                            render={({ Component }) => (
                              <Component {...options} />
                            )}
                          />
                        ) : (
                          <ControlButton {...options} />
                        ),
                      )}
                    </div>
                  )}
                />
              )}
            />
          )
        }}
      />
    </div>
  )
}
갈고리를 사용할 때 다음과 같이 보일 수 있습니다.
import React from 'react'
import useControlPanel from './useControlPanel'
import ControlButton from './ControlButton'

function useAuthValidator({ token }) {
  const [authenticated, setAuthenticated] = React.useState(null)

  React.useEffect(() => {
    if (isAuthed(token)) setAuthenticated(true)
    else setAuthenticated(false)
  })

  return { authenticated }
}

function App() {
  const { authenticated } = useAuthValidator('abc123')
  const { Container, width, height, controls } = useControlPanel({
    authenticated,
  })

  return (
    <Container>
      <div style={{ width, height }}>
        {controls.map((options) =>
          options.render ? (
            <ControlButton
              render={({ Component }) => <Component {...options} />}
            />
          ) : (
            <ControlButton {...options} />
          ),
        )}
      </div>
    </Container>
  )
}

8. 하위 대상과 함께 작업을 통해 구성 요소 논리를 다시 사용합니다


이렇게 명확하게 전달되지 않으면 구성 요소가 어떤 도구를 어떻게 받아들일지 의문이 들 때가 있다.
const DeactivatorInput = ({
  component: Component = 'input',
  style,
  opened,
  open: openModal,
  close: closeModal,
  ...rest
}) => (
  <div>
    <Component
      type="email"
      onKeyPress={(e) => {
        const pressedEnter = e.charCode === 13
        if (pressedEnter) {
          openModal()
        }
      }}
      style={{
        minWidth: 200,
        border: '1px solid rgba(0, 0, 0, 0.5)',
        borderRadius: 4,
        padding: '6px 12px',
        ...style,
      }}
      placeholder="Search a user to deactivate"
      {...rest}
    />
    <Modal isOpen={opened}>
      <h1>Modal is opened</h1>
      <hr />
      <button type="button" onClick={closeModal}>
        Close
      </button>
    </Modal>
  </div>
)

function App() {
  return (
    <ControlPanel>
      <DeactivatorInput />
    </ControlPanel>
  )
}
이해할 수 있는 것은 이 코드의 유효성에 대한 의문이다. 왜냐하면 우리는 어떤 도구가 전달되는 것을 보지 못했기 때문이다. DeactivatorInput. 그러나 실제로는 방법이 있다.
부품뿐만 아니라 필요에 따라 추가 도구를 주입하여 원소를 반응할 수 있는 능력이 있어 좋다.React.cloneElement 다음과 같은 이점을 누릴 수 있습니다.
function ControlPanel({ children, ...rest }) {
  const [opened, setOpened] = React.useState(false)
  const open = () => setOpened(true)
  const close = () => setOpened(false)
  return (
    <div>{React.cloneElement(children, { opened, open, close, ...rest })}</div>
  )
}
React는 어린이를 다룰 때 React.Children.toArray와 함께 여러 어린이에게 사용할 수 있는 다른 유틸리티를 제공합니다. 예를 들어 React.cloneElement:
function ControlPanel({ children, ...rest }) {
  const [opened, setOpened] = React.useState(false)
  const open = () => setOpened(true)
  const close = () => setOpened(false)
  const child = React.Children.toArray(children).map((child) =>
    React.cloneElement(child, { opened, open, close, ...rest }),
  )
  return <div>{child}</div>
}
이러한 전략은 통상적으로 실현될 때 사용된다. 그러나 현재 이런 유사한 기능을 실현하는 가장 좋은 방법은 사용react context이다. 왜냐하면 앞의 해결 방안의 단점은 바로 하위 등급만 React.cloneElement에 전달되는 도구를 수신할 수 있고, 각 끼워 넣은 하위 등급에서만 귀속을 실행할 수 있기 때문이다. (이것은 불필요한 것이다.)react context를 사용하면 하위 대상을 어떤 위치에 두어도 동기화할 수 있습니다.
Rumble charts는 아이의 행동을 결정하기 위해 대량으로 사용된 성공적인 예이다.

9. 깊이 중첩된 어셈블리를 동적으로 생성


이 절에서 우리는 recursion 및react 구성 요소를 사용하는 과정을 간소화하는 데 도움을 줄 수 있는 방법을 소개할 것이다.
네비게이션 표시줄 같은 반복 요소를 포함하는 구성 요소가 있다면, 밑에 있는 메뉴 단추를 포함합니다.드롭다운 목록에는 여러 항목이 있을 수 있으며 각 항목마다 다음과 같은 네스트된 드롭다운 목록이 있을 수 있습니다.

우리는 스스로 플러그인 메뉴를 작성하고 싶지 않다.우리가 수행해야 할 유일한 수동 작업은 컴파일 반복입니다.
import React from 'react'
import Button from '@material-ui/core/Button'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import './styles.css'

const items = [
  { to: '/home', label: 'Home' },
  { to: '/blog', label: 'Blog' },
  { to: '/about', label: 'About' },
  { to: '/contact', label: 'Contact' },
  {
    to: '/help-center',
    label: 'Help Center',
    items: [
      { to: '/privacy-policy', label: 'Privacy Policy' },
      { to: '/tos', label: 'Terms of Service' },
      { to: '/partners', label: 'Partners' },
      {
        to: '/faq',
        label: 'FAQ',
        items: [
          { to: '/faq/newsletter', label: 'Newsletter FAQs' },
          { to: '/faq/career', label: 'Employment/Career FAQs' },
        ],
      },
    ],
  },
]

const MyMenu = React.forwardRef(
  ({ items, anchorEl: anchorElProp, createOnClick, onClose }, ref) => {
    const [anchorEl, setAnchorEl] = React.useState(null)
    return (
      <Menu
        ref={ref}
        open={Boolean(anchorElProp)}
        onClose={onClose}
        anchorEl={anchorElProp}
        anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
        transformOrigin={{ vertical: 'top', horizontal: 'right' }}
      >
        {items.map((item) => (
          <div key={item.to}>
            <MenuItem onMouseEnter={item.items && createOnClick(setAnchorEl)}>
              {item.label}
            </MenuItem>
            {item.items && (
              <MyMenu
                key={item.to}
                items={item.items}
                anchorEl={anchorEl}
                createOnClick={createOnClick}
                onClose={() => setAnchorEl(null)}
              />
            )}
          </div>
        ))}
      </Menu>
    )
  },
)

function App() {
  const [anchorEl, setAnchorEl] = React.useState(null)
  const createOnClick = (callback) => {
    return (e) => {
      e.persist()
      return callback(e.currentTarget)
    }
  }

  return (
    <div>
      <Button onMouseEnter={createOnClick(setAnchorEl)} variant="outlined">
        View More
      </Button>
      <MyMenu
        items={items}
        anchorEl={anchorEl}
        createOnClick={createOnClick}
        onClose={() => setAnchorEl(null)}
      />
    </div>
  )
}
이런 구성 요소를 만드는 것은 구성 요소를 다시 사용할 수 있고 동적으로 만들 수 있는 좋은 방법입니다.
medium에서 나를 찾았다

좋은 웹페이지 즐겨찾기