Это явно антипаттерн и, возможно, ошибка, в зависимости от условий.Статический метод класса не должен работать с экземпляром класса.staticMethod
привязан к конкретному экземпляру компонента и использует setState
, это может быть оправдано только тем, что класс является синглтоном (хотя синглтон также часто является антипаттерном).Это приведет к ошибкам и утечкам памяти, если ожидается более одного экземпляра класса, и каждый компонент React должен иметь более одного экземпляра, по крайней мере для тестирования.
Правильный способ взаимодействия двух независимых компонентов.друг с другом в React должен иметь общий родительский компонент, который обеспечивает это взаимодействие, например:
class ModalContainer extends Component {
modalRef = React.createRef();
render() {
return <>
<Modal ref={this.modalRef} />
<SomeComponentThatUsesModal modalRef={this.modalRef} />
</>;
}
}
Проблема с примером выше состоит в том, что для этого потребуется глубоко передать modalRef
prop, если <SomeComponentThatUsesModal>
nested.
Эта проблема решается с помощью контекста React или других сторонних глобальных решений, таких как Redux.
Это можно сделать с помощью API контекста React 16.3, учитывая, что экземпляр класса Modal
имеетopen
method:
const ModalContext = React.createContext();
function getModal(modalRef) {
return {
open: data => modalRef.current.open(data);
close: () => modalRef.current.close();
}
}
class ModalContainer extends Component {
modalRef = React.createRef();
render() {
return <>
<Modal ref={this.modalRef} />
<ModalContext.Provider value={getModal(this.modalRef)}>
{this.props.children}
</ModalContext.Provider>
</>;
}
}
Тогда для любого глубоко вложенного компонента модальный объект с open
и методы close будут доступны через контекст:
const SomeComponentThatUsesModal = props => <div>
<ModalContext.Consumer>
{modal => <button onClick={() => modal.open('foo')} />}
</ModalContext.Consumer>
</div>;
<ModalContainer>
...deeply nested component
<SomeComponentThatUsesModal />
...
</ModalContainer>
Вот демо .