물통 릴레이에 관한 문제를 생각하다

프로포즈의 물통 릴레이에 관해서는 내가 생각한 것을 적어 두겠다.
첫 학자, 독학, 첫 기고라는 세 단계이기 때문에 문제가 있으면 댓글로 남겨주세요.

물통 릴레이는 나쁜 게 아니에요.


개인적으로 물통 계주 자체가 나쁜 것은 아니라고 생각한다.Props 요소를 부모로부터 아이에게 맡기면 의존관계는 요소에서 쉽게 해석되고 통제가 간단한 경우는 개인 제작에만 한정되는 경우가 많다.
예를 들어 블로그 투고의 편집 화면을 고려할 때 다음과 같은 구성 요소가 있다고 가정한다.
const Page = () => {
   const post = usePost({id: '001'})
   if (!post) {
      return <Loading/>
   }
   return (
      <>
         <PostEditHeader post={post}/>
         <FlexBox>
            <PostEditorDisplay post={post} />
	    <PostEditorSidebar post={post} />
         <FlexBox />
      </>
   )
}
는 상당히 얕은 예이지만 본 예Page에서 얻지 못할 때投稿(post)는 계속 나타난다.
투고의 취득은 ローディング画面(<Loading/>)가 책임지고 관리하기 때문에 아래의 하위 구성 요소는 투고의 취득 여부에 신경 쓰지 않고 취득하거나 애매한 상태에서 사용할 수 없는 구성 요소로 정의할 수 있다.
또한 서브어셈블리는 PageProps 항목이 있으므로 컨텐츠의 구현을 보지 않아도 됩니다.
"이 부품은 투고의 역할을 얻지 못했다."
"이 구성 요소를 사용하기 위해서는 투고를 받아서 제출해야 합니다."
알겠습니다.
나는 투고를 얻고 표시하기 전의 일을 고려했다.
다음은 이 투고를 편집할 때의 일을 생각해 보겠습니다.

물통을 통해 릴레이로 전달되는 요소를 편집하다


export const PostEditorSideBar = (props: {
   post: Post
}) => {
   return (
      <>
         <SideTextField
            title={'スラッグ'}
            subTitle={'SLUG'}
            description={`投稿のスラッグを設定します。`}
            defaultValue={props.post.slug}
            onInput={(s) => (props.post.slug = s)}
          />
	  <SideSwitchField
            title={'公開設定'}
            subTitle={'PUBLISH'}
            description={`Webサイト上における投稿の公開・非公開を設定します。`}
            state={props.post.publish}
            onSwitch={(s) => (props.post.publish = s)}
          />
      </>
   )
}
발언을 편집하는 비속어 등의 사이드바를 예로 들어 썼다.
필드마다 업데이트가 있으면 편집post에서 제출한 Props입니다.投稿(post)에서 교부된 대상은 교부 값이 아니라 참조 교부이기 때문에 Props에서 편집한 내용도 모 어셈블리의 발언에 반영된다.(부모님께 알려지지 않는다)

첫 번째 알림 요소 편집


편집만 하면 괜찮을 것 같아PostEditorSidebar 그리고編集時に何かアクションしたい면 어쨌든'편집했어, 주의해!'이러한 신호는 서브어셈블리에서 서브어셈블리로 보내야 합니다.
내 머릿속에 갑자기 떠오르는 것은 アクションの制御を親コンポーネントでしたい 편집할 때 실행할 함수를 정의하는 것이다.
export const PostEditorSideBar = (props: {
   post: Post
   onChange: (post: Post) => void
}) => {
   return (
      <>
         <SideTextField
            title={'スラッグ'}
            subTitle={'SLUG'}
            description={`投稿のスラッグを設定します。`}
            defaultValue={props.post.slug}
            onInput={(s) => {
	       props.post.slug = s
	       props.onChange(props.post)
	    }}
          />
	  <SideSwitchField
            title={'公開設定'}
            subTitle={'PUBLISH'}
            description={`Webサイト上における投稿の公開・非公開を設定します。`}
            state={props.post.publish}
            onSwitch={(s) => {
	       props.post.publish = s
	       props.onChange(props.post)
	    }}
          />
      </>
   )
}
이렇게 하면 발언을 편집할 때 부모 구성 요소가 정의한 희망적인 동작을 할 수 있다.
이렇게 하면 해결된다!내 생각엔...
계층이 깊으면 Props복잡해질 때도 있다고 생각해요.
const Page = () => {
   const post = usePost({id: '001'})
   const onChange = (post: Post) => console.log(post)
   if (!post) {
      return <Loading/>
   }
   return (
      <>
         <PostEditHeader post={post}/>
         <PostEditor post={post} />
      </>
   )
}

const PostEditor = (props: {
   post: Post
   onChange: (p: Post) => void
}) => (
   <FlexBox>
      <PostEditorDisplay post={post} />
      <PostEditorSidebar post={post} onChange={(post) => props.onChange(post)} />
   </FlexBox>
)
이런 부품을 새로 제작Props해 3층으로 만들어 봤다.
나 개인적으로는
"인수인계만 하는 프롭스가 물통 릴레이를 복잡하게 만든 것 아닌가요?"
그러니까PostEditor 이 구성 요소의 역할은 발언 편집과 관련된 구성 요소를 정리하는 것이기 때문에 디자인이 좀 좋지 않다고 생각하지만 구성 요소를 더욱 잘 예측하기 위해 정리하면 괜찮을 것 같다고 생각합니다.
나도 처음에 말했잖아, 그래도 괜찮은 것 같아.
투고 상태만 PostEditor 관리할 수 있기 때문에 아래의 부품에 대해 쓸데없는 걱정을 할 필요가 없다.
하지만 이게 더 깊어지면 구성 요소의 뜻과 맞지 않는 Proops에도 맡길 필요가 있다고 생각합니다.이런 상황에서 먼저 디자인을 다시 하고 그 다음에 어떻게든 그 디자인을 하고 싶을 때 제 경우Page 등에서 컨디션을 전 세계로 관리하는 옵션이 나올 것 같습니다.

물통 릴레이를 중지하고 전 세계 관리를 진행하다

Context로 지금까지Props 교부된 투고를 관리해 봤습니다.
const Page = () => {
   const post = usePost({id: '001'})
   const [editPost, setEditPost] = useContext(PostContext)
   
   useEffect(() => {
      if(post) {
         setEditPost(post)
      }
   }, [post])
   
   if (!post) {
      return <Loading/>
   }
   return (
      <>
         <PostEditHeader />
         <PostEditor />
      </>
   )
}

export const PostEditorSideBar = () => {
   const [post, setPost] = useContext(PostContext) 
   if (!post) {
      return <></>
   }
   return (
      <>
         <SideTextField
            title={'スラッグ'}
            subTitle={'SLUG'}
            description={`投稿のスラッグを設定します。`}
            defaultValue={post.slug}
            onInput={(s) => setPost({...post, slug: s})}
          />
	  <SideSwitchField
            title={'公開設定'}
            subTitle={'PUBLISH'}
            description={`Webサイト上における投稿の公開・非公開を設定します。`}
            state={post.publish}
            onSwitch={(s) => setPost({...post, publish: s})}
          />
      </>
   )
}
Context를 사용하면 지금까지 부모Context로서 발언의 서브어셈블리를 교부받아 독립적으로 발언을 하게 된다.또한 얻은 발언 유지Props의 모든 구성 요소에 대해 같은 업데이트 권한을 가진다.
이렇게 하면 컨트롤의 난이도가 높아진다.각 구성 요소로 상태를 공유하는 것은 쉬워졌지만, 다른 한편으로는 어떤 고장이 발생하면 원인을 정하기 어렵다.
업데이트 실행을 제한하는 곳을 통해 모든 구성 요소로 상태를 적절하게 관리할 수 있다고 생각합니다.

결론은?


시행착오로 결론이 나지 않아...
지금 나는 다음과 같은 순서로 설계하는 것이 비교적 좋다고 생각한다.
  • 부모가 상태를 관리하고 Proops를 통해 통형 계전기
  • 전체적으로 Context를 사용하여 상태 관리(Proops의 등급이 깊고 무의미한 Proops에 중계된 구성 요소가 존재하는 경우)
  • 좋은 웹페이지 즐겨찾기