Mobx observable и componentDidUpdate () не работает должным образом при прохождении реквизита [Typescript React] - PullRequest
0 голосов
/ 27 июня 2019

Я использую реагировать + mobx + машинопись и хочу отправить массив json из моего логического слоя в компонент пользовательского интерфейса.JSON происходит от асинхронного вызова API.Я сохраняю его в переменной mobx @observable и отправляю как реквизиты в свой компонент пользовательского интерфейса. Я полагаюсь на componentDidUpdate() в своем пользовательском интерфейсе, чтобы определить, когда происходят изменения, так как это происходит из вызова API.работает как ожидалось.

Вот урезанная версия моего логического компонента:

@observer
class DeadletterLogic extends Component<Props, State> {

    @observable queues: any[];
    @observable deadletterQueues: any[];
    @observable temp: any;

    private service: DeadletterService;

    constructor(props: any) {
        super(props);

        // create new service object
        this.service = new DeadletterService();
        this.returnDeadletterInfo(this.service);

    }

    async returnDeadletterInfo(service: DeadletterService) {  
        await this.getQueues(this.service); // get all queues from the service layer
        await this.getDeadletters(this.service);
    }

     async getQueues(service: DeadletterService) {
        // in order to gets a list of queues here, a fetch call must be made in the service layer to the MessageQueueAPI

        let queues = await service.getQueues(); // gets a json array of all the queues

        this.queues = queues.map(data =>
                 data.id
        );

    }

    async getDeadletters(service: DeadletterService) {

        this.deadletterQueues = []; // initialize the array
        let queues = this.queues;

        for (var i = 0; i < queues.length; i++) {
            let queueToGet = queues[i]; // gets current queue name
            let deadletters = await service.getByQueue(queueToGet); // gets the json object with this name from service layer
            this.deadletterQueues.push(deadletters); // pushes that object onto the array
        }
    }

    render() {
        return (
            <div>
                <Deadletters deadletterQueues={this.deadletterQueues}/>         
            </div>
        );
    }
}

А вот урезанная версия моего пользовательского интерфейса:

    deadletterQueues: any[];
}

interface State {
    loading: boolean
}

@observer
class Deadletters extends Component<Props, State> {

    @observable oneDeadletter: any;

    constructor(props: any) {
        super(props);
        this.state = { loading: true };
    }

    componentDidUpdate(prevProps) {
        if (this.props.deadletterQueues !== prevProps.deadletterQueues) {
            // here is where I would map the information I need, but this is only hit once
        }
    }

    render() {
        return (
            <div>
                {this.oneDeadletter}
            </div>
        );
    }
}

Проблема в том, чтоcomponentDidUpdate запускается только один раз, поэтому все, что я могу получить от props.deadletterQueues в дочернем компоненте, - это начальное значение prop (я хочу, чтобы компонентDidUpdate срабатывал каждый раз, когда массив @observable помещается (или изменяется) вродительский компонент, так что я могу извлечь данные из него в пользовательском интерфейсе.

Еще более запутанно, я получаю желаемую функциональность обновления реквизита в дочернем компоненте, если я изменяю свой логический уровень на что-то вроде:

    this.temp = deadletters.map(data =>
        data.messageId);
    this.deadletterQueues.push(this.temp); // pushes that object onto the array

и вместо этого нажмите this.temp в качестве реквизита. Однако мне нужно иметь возможность отображать из пользовательского интерфейса, так что это не работает для меня. Я изо всех сил пытаюсь понять, почему один из нихВ результате действия componentDidUpdate срабатывает, когда @observable в родительском элементе изменяется, а другой нет.

Любая информация об этом очень приветствуется.Я полагаю, что это вещь mobx и связана с передачей значений в массив, который не распознается как изменение, но я не уверен в этом.

1 Ответ

0 голосов
/ 27 июня 2019

Пожалуйста, попробуйте вставить одну строку в функцию render.

    render() {
        const { deadletterQueues } = this.props;
        return (
            <div>
                {this.oneDeadletter}
            </div>
        );
    }

На самом деле, я не знаю причину.

Это очень похоже на мой случай здесь .

Я уточню свой ответ, когда найду причину.:)

РЕДАКТИРОВАТЬ : Я нашел причину:

MobX отслеживает только те данные, к которым обращаются компоненты наблюдателя, если к ним напрямую обращается render

Для более подробной информации: проверьте их ниже

здесь и здесь

...