ReactJs: поток управления во вложенных компонентах

У меня есть компонент A(bigger container), который вызывает два других компонента B(say a kind of header) и C (input form). Теперь мне нужно скрыть заголовок шоу с учетом поведения пользователя на C.

У меня есть решение, в котором A передает функции в качестве реквизита в C, который C может вызывать и изменять состояние в A. Это измененное состояние передается в B, который изменяет текст в B.

Минимальный жизнеспособный пример: -

A: Содержит состояние с focused и вызывает компоненты B и C

class A extends React.Component {
  state = {
    focused: true,
  }

  onFocus = () => {
    this.setState({ focused: true });
  }

  onBlur = () => {
    this.setState({ focused: false });
  }
  render() {
    return (
      <div>
        <C onFocus = { this.onFocus } onBlur = { this.onBlur } focus = { this.state.focused } />
        <B focus = { this.state.focused } />
      </div>
    );
  }
}

B: просто покажите другой текст на основе реквизита из A

const B = (props) => (
  props.focus ? <div> Focussed </div> : <div> Blurred </div>
);

C: содержит текстовое поле ввода, которое выполняет функции из A по действию пользователя

class C extends React.Component {
  state = {
    value: '',
  }

  handleChangeEvent(event) {
    this.setState({ value: event.target.value });
  }

  render() {
    return (
      <input type = "text"
        value = { this.state.value }
        onChange = { this.handleChangeEvent }
        onFocus = { this.props.onFocus }
        onBlur = { this.props.onBlur }
        focus = { this.props.focus }
      />
    );
  }
}

Однако в моем реальном приложении у меня есть несколько компонентов между A и C (A, вызывающий A1, вызывающий A2 ...), и чтобы сделать эти функции доступными, все промежуточные компоненты должны получить их как реквизиты.

Есть ли более изящный способ решить это требование, чтобы все мои промежуточные компоненты не получали эти реквизиты (предназначенные только для дальнейшей передачи)?

Если в конечном итоге у вас будет много буровая установка, возможно, стоит изучить решение для управления состоянием, такое как MobX или Redux.

Tholle 07.08.2018 20:35

может реагировать на контекст

Daniel Khoroshko 07.08.2018 20:35

@DanielKhoroshko Я читал о контексте api, но я не могу привести пример этого. Не могли бы вы помочь мне с этим.

Rhythm Walia 07.08.2018 20:56

@Tholle Есть возможность решить эту проблему без редукции? Это зависимость, которую я не могу предложить только для этого варианта использования. Кстати, я читаю ссылку, которую вы предоставили

Rhythm Walia 07.08.2018 20:57

Ознакомьтесь с этой статьей, Передача нескольких дочерних элементов компоненту React со слотами (раздел Use Children to Pass Props Directly), в которой рассматривается проблема prop drilling. Суть в том, что вы передаете компоненты, которые уже содержат реквизиты, а контейнеры просто отображают их как дочерние.

dance2die 07.08.2018 22:36
Поведение ключевого слова "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) для оценки ваших знаний,...
1
5
116
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я смог сформировать пример решения вышеуказанной проблемы с использованием контекста. Задайте контекст в компоненте более высокого уровня в нашем примере A.

const ConveyorBelt = React.createContext();
class A extends React.Component {
  state = {
    focus: true,
    onFocus: () => {
      this.setState({ focus: true });
    },
    onBlur: () => {
      this.setState({ focus: false });
    },
  }

  render() {
    const { focus } = this.state;
    return (
      <div>
        <ConveyorBelt.Provider value = { this.state }>
          <C />
        </ConveyorBelt.Provider>
        <B focus = { focus } />
      </div>
    );
  }
}

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

const C = () => (
  <ConveyorBelt.Consumer>
    { (context) => (
      <input
        onBlur = { context.onBlur }
        onFocus = { context.onFocus }
        autoFocus = { context.focus }
      />
    ) }
  </ConveyorBelt.Consumer>
);

Теперь мы можем изменить текст в B, который мы хотели, используя состояние A.

const B = (props) => (
  <div>
    { props.focus ? 'Focused' : 'Blurred' }
  </div>
);

Между A и C может быть столько компонентов, и нет необходимости передавать реквизиты всем из них. Только C может читать данные, передаваемые A, что решает проблему бурения опор.

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