首页 > 解决方案 > socket.on 外部数组为空

问题描述

我知道这与 javascript 的异步特性有关,但让我解释一下这个问题,因为我已经为此苦苦思索了一段时间。

问题: 我有一些来自服务器的数据。在我的客户端,我有一个this.socket.on, 在其中我从服务器获取数据并尝试将其推送到我在套接字连接开始之前实例化的数组中。我需要将数据保留在套接字连接之外。

这是代码......任何帮助将不胜感激:

componentDidMount() {
		this.table_data = [];

		// GET ALL EARTHQUAKES 
	    this.socket = io('localhost:9000', {reconnection: true});

	    this.socket.on('all_quakes_event', (data) => {	    	

		  	if (data) {	    			  				    	
		    	data.features.forEach((el, idx) => {
		    		this.table_data.push(
						{
						    key: el.id,
						    mag: el.properties.mag,
						    time: moment(el.properties.time).format('MMMM Do YYYY, h:mm:ss a'),
						    time_readable: moment(el.properties.time).startOf('hour').fromNow(),
						    title: el.properties.title
					  	},
		    		)		    		
				});				
			} // END IF
	    	console.log(this.table_data); // GOOD
	    }); // END SOCKET EVENT	 

	    console.log(this.table_data); // EMPTY

	}

标签: javascriptnode.jsreactjsasynchronoussocket.io

解决方案


存储table_data在组件状态中,然后使用setState(或者,在功能组件中,useState钩子)来更新它:

state = {
  table_data: []
}

componentDidMount() {

        // GET ALL EARTHQUAKES 
        this.socket = io('localhost:9000', {reconnection: true});

        this.socket.on('all_quakes_event', (data) => {          

            if (data) {

                const newData = data.features.map((el, idx) => {
                        return {
                            key: el.id,
                            mag: el.properties.mag,
                            time: moment(el.properties.time).format('MMMM Do YYYY, h:mm:ss a'),
                            time_readable: moment(el.properties.time).startOf('hour').fromNow(),
                            title: el.properties.title
                        }               
                });
                this.setState({ table_data: [...this.state.table_data, ...newData] }) // not sure exactly what you want to do with new data vs existing state, but this pattern should work regardless.     
            } // END IF
            console.log(this.table_data); // GOOD
        }); // END SOCKET EVENT  

        console.log(this.state.table_data); // will be empty until some data comes in from the socket.

    }

推荐阅读