Передайте реквизит всем его детям

Я реализую вложенный компонент, и все мои компоненты должны иметь опору Переменная, теперь у меня есть:

<Parent variable = "myVariable">
   <Child1 variable = "myVariable" />
   <Child2 variable = "myVariable" />
</Parent>

Но я не хочу передавать опору напрямую каждому компоненту, и мне нужно что-то вроде этого:

<Parent variable = "myVariable">
    <Child1 />
    <Child2 />
</Parent>

и мне нужно получить доступ к переменная опора из Ребенок1 и Ребенок2.

Возможно, может помочь реализация Parent как HoC, который передает опору своим детям?

Chirag Ravindra 09.04.2018 07:17

Вы можете попробовать Компонент высшего порядка

Michael Elliott 09.04.2018 07:18

Вы также можете изучить контекст, который больше не является экспериментальным.

h3rmanj 09.04.2018 07:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
3
2 192
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете передать детей в качестве реквизита для родительского элемента:

   class Wrapper extends React.Component {
     render() {
      return (
        this.props.wraps.map(El => <El {...this.props} />);
     };
    }
  }

Итак, вы можете:

  <Wrapper wraps = {[Child1, Child2]} variable = "whatever" />

На самом деле мне нужно сохранить структуру DOM

Sepehr 09.04.2018 07:31
Ответ принят как подходящий

Для этого есть два решения. Использование React.createContext или React.cloneElement в родительском компоненте.

I highly recommend using React.createContext in React 16.3+ since this is exactly what React Context is meant for. Its also especially helpful if you have flow to keep prop type checking working properly.

Note in React 16.6 its even easier to use context by using contextType.

https://reactjs.org/docs/context.html

(или используя create-response-context https://github.com/jamiebuilds/create-react-context), если вы не в курсе.

// parentFile.js
import * as React from 'react';

export const MyContext = React.createContext(); // React.createContext accepts a defaultValue as the first param

type Props = {
  variable: string,
  children: React.Node
};

class Parent extends React.Component<Props> {
  render() {
    return (
       <MyContext.Provider value = {{ variable: this.props.variable }}>
         {this.props.children}
       </MyContext.Provider>
    );
  }
}

class Child1 extends Component<{}> {
  static contextType = MyContext;
  render() {
    return (<div>{this.context.variable}</div>);
  }
}

// IF you have a child in a different file make sure you import the correct consumer
// child2.js
import * as React from 'react';
import { MyContext } from './parentFile';

class Child2 extends Component<{}> {
  static contextType = MyContext;
  render() {
    return (<span>{this.context.variable}</span>);
  }
}

React.createContext сияет здесь, где вы можете обрабатывать вложенные компоненты

// Example of using Parent and Child

import * as React from 'react';

class SomeComponent extends React.Component<{}> {

  render() {
    <Parent variable = "test">
      <Child1 />
      { /* Previously you couldn't use 
           React.cloneElement to handle the nested case */ }
      <SomeOtherComp>
        <Child2 />
      </SomeOtherComp>
    </Parent>
  }
}

This is a quick example of how to do this without React Context and using React.cloneElement

import * as React from 'react';

class Parent extends Component {
  render() {
    const { children, props } = this.props;
    return (
      React.Children.map(children, child =>
        React.cloneElement(child, {...props})
      )
    );
  }
}

не могли бы вы привести пример jsx?

Sepehr 09.04.2018 07:30

Именно для этого и был разработан createContext . Другой вариант - использовать Redux для обработки информации, но это серьезное обязательство, если вы еще не внедрили Redux в свое приложение.

Andrew 09.04.2018 08:14

@KennethTruong Что делать, если у нас есть динамический дочерний компонент? Например, я хочу иметь компонент AnotherChild. Должен ли я добавить еще один ChildConsumer для этого компонента? Потому что я упомянул <Child1 /> и <Child2 />. но в этом примере я вижу только <Child /> На самом деле я хочу получить доступ к переменной в каждом дочернем компоненте, а не только в <Child />

Sepehr 09.04.2018 08:25

Собственно, подумав об этом. Если у вас есть динамический дочерний элемент, вам придется добавить ChildConsumer во все дочерние компоненты. Или вы всегда можете использовать мое второе решение, которое должно работать с динамическими детьми.

Kenneth Truong 09.04.2018 08:29

Другой вариант для динамических компонентов - добавить React.Element в реквизиты, но я рекомендую просто использовать ChildConsumer для любых дочерних компонентов, которые в нем нуждаются.

Kenneth Truong 09.04.2018 08:34

Да, ReactContext может использоваться вложенными компонентами! Просто используйте тот же ContextConsumer

Kenneth Truong 09.04.2018 08:34

Я обновил свой пример, чтобы показать Child1, Child2 и NestedComponent. Позвольте мне знать, если это помогает

Kenneth Truong 09.04.2018 19:16

Что делать, если Child1 и Child2 находятся в разных файлах? Все примеры, которые я вижу, предполагают, что они находятся в одном файле. У меня возникают проблемы с тем, чтобы это работало, когда дети находятся в других файлах.

james emanon 21.07.2018 07:45

@jamesemanon, если дети находятся в разных файлах. Вы должны убедиться, что экспортируете ChildConsumer и импортируете его в разные дочерние файлы.

Kenneth Truong 21.07.2018 12:54

// parentFile.js const {Provider, Consumer} из React.createContext (); экспорт const SomeConsumer = Consumer; // Импорт дочернего файла 1 {SomeConsumer} из 'parentFile'; // Импорт дочернего файла 2 {SomeConsumer} из 'parentFile';

Kenneth Truong 21.07.2018 12:59

да, я закончил идти этим маршрутом, но это так .... мля. Можно было бы создать своего собственного подписчика (pub / sub), и это, кажется, одно и то же, верно? Итак, для каждого использования createContext у нас должен быть отдельный файл для его экспорта? Кажется инвазивным? нет?

james emanon 22.07.2018 02:52

Если бы вы создали свой собственный pub / sub, у вас было бы больше шаблонного кода. (Поскольку вам нужно вызвать setState и т. д. И сделать pub / sub частью жизненного цикла React. Хотя это будет автоматически отображаться, когда поставщик изменяет значение.)

Kenneth Truong 22.07.2018 06:26

Другие вопросы по теме