Несколько месяцев назад я начал использовать React, большинство из нас может понять, как он становится беспорядочным еще до того, как ваше приложение начинает расти, потому что вы склонны продолжать передавать реквизиты, пока они не доберутся до внутренних компонентов, которые в них нуждаются.

Хотя это нормально, поскольку именно так работает react, но нам не нужен гигантский код, который сложно поддерживать. обычно мы обращались к библиотекам управления состоянием (Redux/Mobx)/новому контекстному API 😜 — сейчас это устаревает. В настоящее время существует множество инструментов, которые могут показаться ошеломляющими, но вы должны знать, когда их использовать, и все будет в порядке, иначе они заставят вас тратить больше времени и снижают вашу производительность. Попытка выяснить, как все работает в контексте, Redux, Mobx или других библиотеках в целом, тоже может оказаться непростой задачей.

Как избавиться от сверления реквизита?

Композиция компонентов!
Вы можете избежать «детализации свойств», передавая компоненты как свойства, чтобы компоненты имели необходимые данные, прежде чем они будут переданы как свойства. для демонстрации мы создадим образец приложения 😜.

Традиционная структура приложения будет выглядеть так:

<App>
<PageLayout/>
 <NavigationBar> 
 <Avatar/>
 </NavigationBar>
 <Main>
 ….
 </Main>
 <PageLayout/>
</App>

Здесь компоненту аватара требуется пользовательское свойство, следуя традиционному способу, которым мы будем передавать пользовательское свойство, пока оно не попадет в ‹Avatar/›, например так:

<App>
 <PageLayout user={user}/>
 <NavigationBar user={user}> 
 <Avatar user={user}/>
 </NavigationBar>
 <Main/>
 <PageLayout/>
</App>

Кажется излишним передавать пользовательскую поддержку через многие уровни, если в конце концов она действительно нужна только компоненту аватара. Также раздражает то, что если компоненту аватара требуется больше реквизитов сверху, вы должны помнить, чтобы добавить его и на всех промежуточных уровнях. . Итак, как мы составим наши компоненты для решения этой проблемы?

Решение

<App>
 <PageLayout>
 <NavigationBar avatar={<Avatar user={this.state.user} />} />
 <Main user={this.state.user}/>
 </PageLayout>
</App>

Ага! я знаю, о чем вы думаете — я не сформулировал мысль даже @dan_abramov твитнул об этом и добавил раздел в ReactJS Docs

Давайте посмотрим на полный код

class App extends Component {
constructor(props) {
   super(props);
    this.state = {
     user: {
     name: “Prof. Yemi Osinbajo”,
     image: “https://i1.wp.com/techpoint.afric...",
     position: “VICE PRESIDENT. NIGERIA”
  }
  }
 }
 
 render() {
 return (
   <AppWrapper>
     <PageLayout>
       <NavigationBar avatar={<Avatar user={this.state.user} />} />
       <Main user={this.state.user}/>
     </PageLayout>
    </AppWrapper>
  );
 }
}

‹AppWrapper› выше — это всего лишь стилизованный компонент, пытающийся немного стилизовать приложение. Вы можете видеть, как мы передали свойство пользователя компоненту аватара, не сообщая об этом большинству компонентов?

Другие компоненты будут выглядеть так

const PageLayout = ({children}) => {
 return (
   <PageLayoutWrapper>
     {children}
    </PageLayoutWrapper>
 );
}
const NavigationBar = ({avatar}) => {
 return (
    <NavbarWrapper>
      {avatar}
    </NavbarWrapper>
 ); 
}
const Main = ({ user }) => { 
 return (
   <MainWrapper>
     <Card>
       <Image src={user.image} />
      <UserInfo>
       <UserName>{user.name}</UserName>
        <UserPosition>{user.position}</UserPosition>
          <Image small src={NG}/>
       </UserInfo>
     </Card>
    </MainWrapper>
 )
}
const Avatar = ({ user }) => {
 return (
    <Image small rounded src={user.image} />
 )
}

Это было довольно прямолинейно! , Мы передаем компоненты в качестве реквизита! и это спасает нас от сверления пропеллеров. Однако это следует использовать с осторожностью.

Когда тогда следует использовать контекст React

Вы должны использовать контекст, когда одни и те же данные должны быть доступны многим компонентам в дереве и на разных уровнях вложенности. Контекст позволяет передавать такие данные и изменения всем компонентам ниже.

Не стесняйтесь проверить код

я @marvinjudehk в твиттере