简体   繁体   中英

Reloading a page in React will result in no props

I have the following code, but when the web page is displayed, this.props.items is not passed to Item. When I try to output this.props.items in console.log , nothing is displayed. However, when the page is automatically refreshed by saving it in the code editor instead of reloading the page, this.props.items is properly passed.

Why is this happening? I would appreciate it if you could tell me more about it.

import React, { Component } from 'react';
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { getItems } from '../../actions/items'


class Container extends Component {
    static propTypes = {
        items: PropTypes.array.isRequired,
        getItems: PropTypes.func.isRequired,
    }
    componentWillMount() {
        this.props.getItems();
    }
    render() {
        return (
            <Item timetable={this.props.items} />
        );
    }
}

const mapStateToProps = (state) => ({
    items: state.items.items,
});

export default connect(mapStateToProps, { getItems })(Container);
export const getItems = () => (dispatch, getState) => {
    axios.get(`${url}/items/`, tokenConfig(getState))
        .then(res => {
            dispatch({
                type: GET_ITEMS,
                payload: res.data
            })
        }).catch(err => console.log(err));
}

When you save a file in your code editor, React refreshes the app but retains as much of the state as possible, so that you can keep working without needing to redo a lot of steps to get where you're working on. But when you refresh the page, the whole app is restarted from zero and all state is lost. You can avoid this behavior and save the state you want to persist by using localStorage or sessionStorage . You can do this in the context of React and Redux using Redux Persist .

Most probably the issue would be that your backend API response time is more than what you had expected. It's always a good practice to check whether the data that you fetch from your backend API is actually present, in the sense not null/not empty. The most common counter to this is to use a Loader component and wait until the whole data is fetched from server.

class Container extends Component {
    static propTypes = {
        items: PropTypes.array.isRequired,
        getItems: PropTypes.func.isRequired,
    }
    componentWillMount() {
        this.props.getItems();
    }
    render() {
        if (!this.props?.items) return (<p>Loading...</p>); // --> Use a guard clause

        return (
            <Item timetable={this.props.items} />
        );
    }
}

Please go through these references to understand more clearly the points I have elaborated:

  1. How to handle AJAX requests - Official React Docs
  2. Why use guard clauses?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM