Абсолютно простой пример функционального наблюдаемого шаблона в React

#reactjs #components #observer-pattern

#reactjs #Компоненты #наблюдатель-шаблон

Вопрос:

Может ли кто-нибудь предоставить глупо-простой пример наблюдаемого в ReactJS?

По сути, я хочу передать сообщение от одного компонента к другому.

Поисковые запросы Google отправили меня в кроличьи норы с RxJS, Redux, хуками, разделяемой памятью, компонентами на основе классов и другими вовлеченными темами.

Возьмем, к примеру, следующую структуру:

     A
   / 
  B   C
 /
D  E
  

Мне просто нужно отправить сообщение true / false из компонента D в C.

Является ли это изначально сложным в React? tyvm, Кит :^)

Комментарии:

1. digitalocean.com/community/tutorials/react-usecontext

2. medium.com/@danfyfe/…

3. reactjs.org/docs/context.html

4. youtube.com/watch?v=rFnfvhtrNbQ

Ответ №1:

RxJS

Redux-observable использует ReactiveX observables, но я не думаю, что это наиболее часто используемый метод для приложений React.

Состояние реакции

Состояние реакции (this.state или useState) передается только от родительского элемента к дочерним элементам, поэтому, когда D и C нуждаются в состоянии, им нужно управлять в общем предке, которым является A. Это означает, что A необходимо передать B реквизиты, которые B не нужны, только для того, чтобы B мог передать их C. Это называется детализацией реквизита и считается плохим, поэтому не лучшим вариантом.

Redux и react-redux

Хранилище Redux — это хранилище событий, вы можете отправлять действия (events), а редукторы или промежуточное программное обеспечение будут реагировать на эти действия для обновления состояния (reducers) или вызывать побочные эффекты (обычно это делается с помощью промежуточного программного обеспечения). Компонент (ы) может использовать селекторы для получения данных из состояния с помощью useSelector(selectorFunction) , ранее использовался HOC connect , но перехват намного проще.

Когда отправляется действие, которое вызывает изменение состояния, все selectorFunction функции вызываются react-redux, и если их возвращаемое значение отличается от последнего запуска, он повторно отобразит компонент, в котором useSelector использовался.

Redux — хороший кандидат, если вам нужно реализовать сложные требования, поскольку шаблон CQRS / event store позволяет легко отделять действия (указать, что произошло) от редукторов (что делать, когда что-то произойдет), и вы можете запросить хранилище с помощью селекторов (обычно используетсяповторный выбор).

Контекст

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

 const BoolContext = React.createContext();
const BoolProvider = ({ children }) => {
  //set bool message to true
  const [bool, setBool] = React.useState(true);
  const toggle = React.useCallback(
    () => setBool((b) => !b),
    []
  );
  return (
    // set value of context to {bool, toggle}
    <BoolContext.Provider value={{ bool, toggle }}>
      {children}
    </BoolContext.Provider>
  );
};

const D = () => {
  const { bool, toggle } = React.useContext(BoolContext);
  return <button onClick={toggle}>D:{String(bool)}</button>;
};
const C = () => {
  const { bool, toggle } = React.useContext(BoolContext);
  return <button onClick={toggle}>C:{String(bool)}</button>;
};
//removed E as it does not do anything to demonstrate context
const B = () => ( <D /> )

const A = () => {
  return (
    <BoolProvider>
      <B />
      <C />
    </BoolProvider>
  );
};

ReactDOM.render(<A />, document.getElementById('root'));  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>  

Комментарии:

1. Отлично, спасибо. Пожалуйста, объясните {children} , что это единственная часть, которая неясна. ty

2. @kmiklas В этом случае дочерние элементы (props.children) BoolProvider являются <B /><C />