Невозможно получить доступ к this.state или this.props вне вызова извлечения .then (json), если я не перенесу console.log (this.state) внутри setTimeout - PullRequest
0 голосов
/ 09 января 2019

Я не могу получить доступ к this.state или this.props за пределами .then(json). Если я попытаюсь сделать console.log(this.state, this.props), Я вижу состояние и реквизиты в журнале, но как только я нажимаю на него, оба массива пусты. Однако, если я оберну console.log вокруг setTimeout(), это сработает. Тем не менее, это создает для меня проблему с областью видимости, потому что мне нужно внедрить состояние из этого компонента в качестве реквизита в компонент FeedTable следующим образом ---

<FeedTable fetch_call={this.state.quakes_list} />

Проблематичным console.log является console.log('QUAKES LIST COMPONENT STATE ', this.state.quakes_list);

Как только я переместил его ниже следующего }), он отобразит пустой []

любая помощь будет высоко ценится! Вот полный код для компонента:

class QuakeFeed extends Component {

    constructor (props) {
        super(props);

        this.state = {
            current_quakes: [],
            quakes_list: []
        }
    }

    componentDidMount() {

        // USE CURRENT TIME TO FETCH LIVE DATA
        // GET DATE AND TIME TODAY
        let time_now = new Date().getTime();
        let date_now = new Date(time_now);
        let data_now = date_now.toString();     

        // SPLIT THE DATE TO EXTRACT TO 'YEAR-MONTH-DAY' FORMAT
        let split_date = data_now.split(' ');

        // SEGREGATE MONTH AND RETURN NUMBER INSTEAD OF MONTH       
        let date_arr = split_date.slice(1,4);

        // SHUFFLE ARRAY TO PROPER FORMAT           
        let year  = date_arr[2];
        let month = date_arr[0];
        let day   = date_arr[1];

        // IF MONTH STRING, PARSE TO NUMERIC
          month === 'Dec' ? month = '12' 
        : month === 'Nov' ? month = '11' 
        : month === 'Oct' ? month = '10' 
        : month === 'Sep' ? month = '09' 
        : month === 'Aug' ? month = '08' 
        : month === 'Jul' ? month = '07'
        : month === 'Jun' ? month = '06' 
        : month === 'May' ? month = '05' 
        : month === 'Apr' ? month = '04' 
        : month === 'Mar' ? month = '03' 
        : month === 'Feb' ? month = '02' 
        : month === 'Jan' ? month = '01' 
        : null;

        // TODAY USING MODIFIED YEAR, MONTH, DATE
        const today = [year, month, day]
        let yesterday = day - 1;        
        yesterday.toString();

        // FETCH CALL TO GET DATA (ARROW FUNCTION TO BIND TO PARENT SCOPE)
        const repeat_fetch = () => {

            // ----------------- INITIAL FETCH -----------------
                // USE THE VARIABLES TO PLUG IN YEAR, MONTH, DAY AND INITIATE FETCH CALL
                fetch ('https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=' + year + '-' + month + '-' + yesterday + 
                       '&endtime=' + year + '-' + month + '-' + day + '&minmagnitude=5')

                .then((response) => {
                    return response.json();
                })

                .then((json) => {       

                    let eq_props = json.features;

                    store.dispatch({ type: 'FETCH-RESPONSE', payload: eq_props })

                    // EARTHQUAKE DATA FROM FETCH 
                    let fetched_req = store.getState();

                    // SET COMPONENT STATE TO STATE FROM REDUX STORE
                    this.setState({current_quakes: fetched_req});                   

                    // LOG CURRENT EARTHQUAKES
                    // console.log('Data', this.state.current_quakes);

                    // CURRENT EARTHQUAKES
                    const quakes = [].slice.call(this.state.current_quakes.quake_data);

                    // STORE QUAKES IN OBJECT TO PACKAGE AND PUSH INTO REDUX STORE
                    let quake_table_data = {};                  

                    for (var i = 0; i < quakes[0].length; i++) {

                        // LOCATION, MAGNITUDE, TIME OF CURRENT EARTHQUAKES
                        const quake_location = quakes[0][i].properties.place;
                        const quake_mag      = quakes[0][i].properties.mag;
                        const quake_time     = new Date(quakes[0][i].properties.time).toLocaleString();

                        quake_table_data.loc = quake_location;
                        quake_table_data.mg  = quake_mag;
                        quake_table_data.tim = quake_time;                      

                        /* 
                            PUSHES THIS OBJECT TO THE REDUX STORE SO THAT YOU CAN ACCESS IT INSIDE 
                            THE FEED TABLE COMPONENT AND CREATE A DYNAMIC TABLE 
                        */
                        store.dispatch({ type: 'STORE-QUAKES', payload: quake_table_data });
                    } // END LOOP                   

                    // GET PROPS FROM mapStateToProps OF REDUX STATE AND SET STATE                  
                    this.setState({ quakes_list: this.props.e_quakes[0]});
                    console.log('QUAKES LIST COMPONENT STATE ', this.state.quakes_list);
                })

            // -------------------------------------------------

            setTimeout(function() {
                // USE THE VARIABLES TO PLUG IN YEAR, MONTH, DAY AND INITIATE FETCH CALL
                fetch ('https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=' + year + '-' + month + '-' + yesterday + 
                       '&endtime=' + year + '-' + month + '-' + day + '&minmagnitude=5')

                .then((response) => {
                    return response.json();
                })

                .then((json) => {                               
                    repeat_fetch();     
                })
            }, 330000);

        } // END repeat_fetch()

        repeat_fetch();
    }
    render() {
        return (
            <div className='section-quake-feed'>

                <FeedTable fetch_call={this.state.quakes_list} />

            </div>
        )
    }
    }

    function mapStateToProps(state) {
        return {
            e_quakes: state.quake_data
        }
    }

    export default connect(mapStateToProps)(QuakeFeed);

1 Ответ

0 голосов
/ 09 января 2019

Причина, по которой quakes_list является пустым массивом, когда вы регистрируете его вне .then, заключается в том, что асинхронный вызов еще не вернулся при вызове console.log. Порядок операций:

  1. Звоните fetch (код в .then не начинается, пока ответ не вернется)
  2. Вызов console.log (потому что это следующая синхронная команда), которая регистрирует пустой массив, который вы инициализировали в this.state
  3. Ответ возвращается с fetch и quakes_list данные установлены в состояние

Надеюсь, это ответит на ваш вопрос ... я полагаю, что у вас также есть проблема с получением <FeedTable> для рендеринга quakes_list, потому что он не установлен в состояние при вызове render. Если это так, то обычным решением является проверка свойства в состоянии и возврат загрузчика, если он не существует:

render() {
  return (
    <div className='section-quake-feed'>
      {this.state.quakes_list.length ? (
        <FeedTable fetch_call={this.state.quakes_list} />
      ) : (
        "Loading..." // Or some fallback Loader component, or `null`
      )}
    </div>
  )
}

Что происходит: render вызывается и возвращает запасной вариант, потому что quakes_list.length равен 0, затем, когда установлено quakes_list, setState вызывает повторный рендеринг, и компонент FeedTable отображается.

...