Как упорядочить объекты, которые используют setState, объявленный в корневом компоненте, в разные файлы? - PullRequest
0 голосов
/ 20 февраля 2019

Я борюсь за реорганизацию своего приложения, написанного на 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;
    });
}

Тогда, как бы вы подошли к этой проблеме?Не могли бы вы оставить это так, зная, что в будущем это может быть немыслимо?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...