传递道具时,Mobx的observable和componentDidUpdate()行为不符合预期[Typescript React]

时间:2019-06-26 22:41:04

标签: reactjs typescript mobx

我正在使用react + mobx +打字稿,并希望将json数组从我的逻辑层发送到UI组件。 json来自异步api调用。我将其保存在mobx @observable变量中,并将其作为道具发送到我的UI组件。我依靠UI中的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值(什么都没有)。我希望每当将@observable数组推入(或修改)父组件中时,componentDidUpdate都可以命中,以便可以在UI中从中提取数据。

更令人困惑的是,如果我将逻辑层更改为以下内容,我确实会在子组件中获得道具更新所需的功能:

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

,然后将this.temp作为道具。但是,我需要能够从UI进行映射,所以这对我不起作用。我正在努力查看为什么其中一个操作导致componentDidUpdate在父级中的@observable更改而另一个未更改时触发。

任何对此的启示将不胜感激。我相信这是一个怪诞的事情,并且与将值推入不被视为更改的数组有关,但是我不确定。

1 个答案:

答案 0 :(得分:0)

请尝试在render函数中插入一行。

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

事实上,我不知道原因。

这与我的案例here非常相似。

找到原因后,我将更新答案。 :)

编辑:我找到了原因:

  

MobX仅跟踪由render直接访问观察者组件的数据

有关更多详细信息,请在下面进行检查

herehere