У меня есть задача создать новый компонент React в существующем проекте. Проект состоит из нескольких подпроектов. Два из них:
WebApp
: содержит большую часть логики приложения, хранилища Redux и «умных» компонентов React, подключенных к хранилищу Redux.
Design
: содержит «немые» компоненты React, которые имеют стилизацию и могут иметь собственное локальное состояние.
Одно из правил проекта гласит, что компоненты Design
можно импортировать в WebApp
, но не наоборот. Таким образом, в случае, если «тупому» компоненту нужно запустить действие хранилища, один из «умных» компонентов должен раскрыть действие с помощью mapDispatchToProps
и передать его до «тупого» компонента.
Проблема с моим новым компонентом заключается в том, что он может использоваться во многих местах проекта, иногда довольно глубоко в цепочке «тупых» компонентов. Таким образом, в случае, если я буду следовать правилам проекта, мне придется обновить множество «тупых» компонентов всеми новыми свойствами, которые должен получить мой компонент.
Чтобы избежать этого, я попытался использовать HOC-подобный «умный» компонент и передать его через контекст React моему «тупому» компоненту. Я говорю «HOC-like», потому что это не классический HOC, а тот, который использует свойство render .
Мой «умный» компонент из WebApp
:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MySmartComponent extends Component {
render() {
return (
<>
{this.props.render({
someAction: this.props.someAction,
})}
</>
);
}
}
const mapDispatchToProps = dispatch => ({
someAction: payload => {
/* something happens*/
},
});
export default connect(mapDispatchToProps)(MySmartComponent);
Мой "тупой" компонент из Design
:
import React, { Component } from 'react';
export const MyContext = React.createContext({});
class MyDumbComponent extends Component {
render() {
return (
<MyContext.Consumer>
{({ MySmartComponent }) => {
return (
<MySmartComponent
render={({ someAction }) => (
<>/* someAction can be used here */</>
)}
/>
);
}}
</MyContext.Consumer>
);
}
}
export default MyDumbComponent;
И затем я предоставляю MySmartComponent
в качестве контекста в некоторых корневых компонентах в WebApp
:
import React, { Component } from 'react';
import { MyContext } from 'Design/MyDumbComponent';
import MySmartComponent from 'WebApp/MySmartComponent';
const myContext = { MySmartComponent };
class SomeRootComponent extends Component {
render() {
return (
/* ... */
<MyContext.Provider value={myContext}>
{this.props.children}
</MyContext.Provider>
/* ... */
);
}
}
export default SomeRootComponent;
Я подозреваю, что это может быть неправильным использованием контекста React. Или, может быть, это просто плохая практика? Но тогда, что может быть минусами?