Я борюсь за реорганизацию своего приложения, написанного на React.Это особый случай, когда я не нашел конкретного ответа для решения моей проблемы.
Я разрабатывал атрибуты моего основного состояния для корневого компонента, группируя их по контексту (не реагируя на контекст) и распространяя ихсодержимое от узла к дочернему узлу, например:
// AppOperator.jsx which is root component
class AppOperator extends Component {
constructor(props) {
super(props);
// first group, attributes and methods regarding cart management
this.CartManager = {
list: [],
methodCM1: this.methodCM1.bind(this),
methodCM2: this.methodCM2.bind(this),
};
// second group, properties related to phase management
this.PhaseManager = {
step: 0,
methodPM: this.methodPM.bind(this),
nextPhase: this.nextPhase.bind(this),
};
this.state = {
CartManager: this.CartManager,
PhaseManager: this.PhaseManager,
}
}
render = () => <View CartManager={this.state.CartManager} {/*...(etc)*/} />
// ...
// CartManager methods
methodCM1 = () => this.setState((state) => {
const { CartManager } = state;
CartManager.list = [];
return state;
});
methodCM2 = () => this.setState((state) => {
const { CartManager } = state;
CartManager.discount = 0.5;
return state;
}, () => this.methodPM());
// ...
// PhaseManager methods
methodPM = () => this.nextPhase();
nextPhase = () => this.setState((state) => {
const { PhaseManager } = state;
PhaseManager.step++;
return state;
});
// ...
// Methods for.... nth object
// ...
}
Как вы можете видеть, могут быть методы из другого объекта, вызываемые внутри.Не будет проблем, если вы оставите их объявление в той же области (this instanceOf AppOperator
).Они будут действовать как «глобальные» переменные.Все видят всех.
Но что, если он будет расти и усложняться?Как вы можете поддерживать такую вещь?
Во-первых, я бы начал использовать React Context вместо распространения объектов от узла к узлу.Никаких проблем с этим.
Затем я бы начал разбивать объекты по разным файлам и вызывать их конструкторы внутри компонента AppOperator следующим образом:
// AppOperator.jsx
import { CartManager, PhaseManager, } from './Managers';
class AppOperator extends Component {
constructor(props) {
super(props);
// this looks pretty pabolouuus!.
this.state = {
CartManager: new CartManager(),
PhaseManager: new PhaseManager(),
['nth-object']: new NthStateObject(),
}
}
render = () => <View CartManager={this.state.CartManager} {/*...(etc)*/} />
}
, а менеджеры - следующим образом:
// CartManager.js
export default class CartManager {
constructor() {
this.list = [];
this.discount = 0;
}
methodCM1 = () => this.setState((state) => {
const { CartManager } = state;
CartManager.list = [];
return state;
});
methodCM2 = () => this.setState((state) => {
const { CartManager } = state;
CartManager.discount = 0.5;
return state;
}, () => this.methodPM());
}
// PhaseManager.js
export default class PhaseManager{
constructor() {
this.step = 0;
}
methodPM = () => this.nextPhase();
nextPhase = () => this.setState((state) => {
const { PhaseManager } = state;
PhaseManager.step++;
return state;
});
}
Это было бы крутое решение, если бы оно могло работать.Подобное разделение оставило бы методы менеджеров для вызова setState без знания контекста AppOperator.
Вместо этого, метод привязки объекта с контекстом AppOperator отказался бы от своих собственных свойств, и это тоже не хорошо:
// PhaseManager.js
export default class PhaseManager{
constructor(that) { // easy not working cheat
this.step = 0;
this.methodPM = this.methodPM.bind(that);
this.nextPhase = this.nextPhase .bind(that);
}
methodPM = () => this.nextPhase();
nextPhase = () => this.setState((state) => {
const { PhaseManager } = state;
PhaseManager.step++;
return state;
});
}
Тогда, как бы вы подошли к этой проблеме?Не могли бы вы оставить это так, зная, что в будущем это может быть немыслимо?