Joeyboy
Joeyboy

Reputation: 472

Component rendering before props are updated - React Redux

When the component is mounted a request is sent to fetch data (API). The component is rendering before this action is called which raises an undefined error.

I am fairly sure I need to implement some kind of loading state but cannot get it to work.

Component:

class Profile extends Component {


  static propTypes = {
    auth: PropTypes.object.isRequired,
    games: PropTypes.array.isRequired,
    getGames: PropTypes.func.isRequired,
    deleteGame: PropTypes.func.isRequired,
    getUser: PropTypes.func.isRequired,
  };

  componentDidMount() {
    this.props.getUser(this.props.match.params.username);
    this.props.getGames(this.props.match.params.username);
  }

  render() {
    const { user } = this.props.auth;
    const queriedUser = this.props.queriedUser;
    const loadingQueriedUser = this.props.loadingQueriedUser;

    // Edit button
    const ownerLink = (
      <div>
        <button>EDIT</button>
      </div>
    );
    const guestLink = <div></div>;

    // if (loadingQueriedUser) {
    //   return <div>Loading...</div>;
    // }

    return (
      <Fragment>
        <div>
          <div className="row mt-2">
            <div className="col-1">
              <img
                className="rounded-circle account-img"
                style={{ height: 100 + "px", width: 100 + "px" }}
                src={queriedUser.profile.profile_image}
              ></img>
            </div>

Action:

  //  GET USER
  export const getUser = (username) => (dispatch, getState) => {

// Loading query
  dispatch({ type: LOADING_QUERIED_USER });

  axios
    .get(`/api/users/${username}`, tokenConfig(getState))
    .then((res) => {
      dispatch({
        type: GET_USER,
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch(returnErrors(err.response.data, err.response.status));
      dispatch({
        type: AUTH_ERROR,
      });
    });
  };

Upvotes: 1

Views: 702

Answers (2)

cd3k
cd3k

Reputation: 812

In your return expression put

return (
  queriedUser &&
  // Rest of your code...
)

Now the element will only render once your queriedUser object has loaded.

Upvotes: 3

Vitaly Menchikovsky
Vitaly Menchikovsky

Reputation: 8884

Hi the simple example is

 if (!data)
    return <Loader  />;
  else
    return (
{{data}}
)

Upvotes: 1

Related Questions