Существует несколько способов, которыми вы можете выполнить sh Реактивная / нереактивная связь.
Использование пользовательских событий
Хотя у каждого метода есть свои плюсы и минусы, этот является преимуществом. Быть рамочной агностией c. Вы можете сделать то же самое для компонента Vue и ванили js. Недостатком является то, что вам нужно найти способ управлять и документировать события в чистом виде, иначе ваше приложение может быстро стать недоступным.
Внутри вашего компонента вам нужно создавать и прослушивать собственные событие. Затем вы можете отправить его из любого места, и компонент будет перехватывать его и обновлять соответствующим образом.
const OPEN_EVENT_NAME = 'open';
const CLOSE_EVENT_NAME = 'close';
const container = document.querySelector('#app');
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: true,
}
// Bind the "open" and "close" events to their respective functions
container.addEventListener(OPEN_EVENT_NAME, this.openModal);
container.addEventListener(CLOSE_EVENT_NAME, this.closeModal);
}
openModal = () => {
this.setState({ open: true });
}
closeModal = () => {
this.setState({ open: false });
}
render() {
return (
<div>The modal is {this.state.open ? 'open' : 'closed'}</div>
)
};
}
ReactDOM.render(<App />, container);
// Create custom events
const openEvent = new Event(OPEN_EVENT_NAME);
const closeEvent = new Event(CLOSE_EVENT_NAME);
// Create events dispatchers
const openModal = () => container.dispatchEvent(openEvent);
const closeModal = () => container.dispatchEvent(closeEvent);
// Dispatch events on buttons click
document.querySelector('#open-btn').addEventListener('click', openModal);
document.querySelector('#close-btn').addEventListener('click', closeModal);
body {
font-family: 'system-ui';
padding: 12px;
}
h2 {
font-weight: bold;
margin: 0;
margin-bottom: 6px;
}
hr {
margin: 12px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<h2>
This is React
</h2>
<div id="app"></div>
<hr>
<h2>
This is not React
</h2>
<button id="open-btn">
Open modal
</button>
<button id="close-btn">
Close modal
</button>
Использование ссылок
Ссылки обычно используются для доступа к базовому элементу DOM компонента React.
Они также могут быть использованы для присоединения компонента к объекту окна, таким образом получая доступ к его состоянию и предоставляя доступ к его методам.
Этот метод менее подвержен ошибкам, поскольку вы говорите на том же языке, что и ваш компонент (состояние, методы и т. Д.). c.) Но это также недостаток, потому что это подразумевает, что конечный пользователь вашего компонента имеет некоторое знакомство с React, а это может быть и не так.
Вот как это сделать. благодаря этой статье .
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: true,
}
}
openModal = () => {
this.setState({ open: true });
}
closeModal = () => {
this.setState({ open: false });
}
render() {
return (
<div>The modal is {this.state.open ? 'open' : 'closed'}</div>
)
};
}
ReactDOM.render(<App ref={myComponent => window.myComponent = myComponent} />, document.querySelector('#app'));
body {
font-family: 'system-ui';
padding: 12px;
}
h2 {
font-weight: bold;
margin: 0;
margin-bottom: 6px;
}
hr {
margin: 12px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<h2>
This is React
</h2>
<div id="app"></div>
<hr>
<h2>
This is not React
</h2>
<button onclick="window.myComponent.openModal()">
Open modal
</button>
<button onclick="window.myComponent.closeModal()">
Close modal
</button>
- Обновление -
Поскольку вы используете перехватчики React и не можете ссылаться на функциональный компонент, я я бы не советовал использовать подход № 2.
Я создал мини-пример того, как я реализую подход № 1 (используя события для взаимодействия с React).
Как указано выше, это обеспечивает гораздо приятнее API для конечных пользователей и может быть самым чистым решением из этих двух.
Это демо доступно здесь.