0
votes

How you guys handle initialstate of your loading state in redux reducer? is it always true? The problem is you have to always set it to false in every single case later in the reducer.

Like so

const initState = {
  loading: true,
  data: null,
  error: null
}

export function global(state=initState, action) {
  switch(action.type){
    case FETCHING: 
      return {
        ...state,
        loading: true
      }
    case FETCH_SUCESS:
      return {
        ...state,
        data: action.payload,
        loading: false
      }
    case FETCH_FAILED:
      return {
        ...state,
        error: action.payload.error,
        loading: false
      }
    default:
      return state
  }
}

If it's set to false you will have this problem

class AClassName extends Component {
  constructor(props){
    super(props)
    props.callAnApi()
  }

  //assume in reducer your loading initialstate is false

  render() {


    this.props.something && return <Redirect to={`/app/${this.props.something}`} />

    return !this.props.loading && <SomethingElse { ...this.props } />
  }
}

How to return nothing if it's finished loading. Above problem is that SomethingElse component will still got rendered once which is not what I want. So what's your initialState of loading?

2
please add reducers - RIYAJ KHAN
@RIYAJKHAN Done, updated my question with reducer added. - Jamie Aden
I default mine to false and set it to true if need be, in your case on call of api, however I would have put it in componentWillMount instead of the constructor. To render would first check if loading, which it would be as the first step of the API call would be to dispatch the 'FETCHING' action which would then set loading to true. Then once the render method is hit as the API call is non-blocking, loading will be true, the loading component will display and on success of API call set loading to false. - RemeJuan

2 Answers

1
votes
const initState = {
  loading: false,
  data: null,
  error: null
}

export function global(state=initState, action) {
  switch(action.type){
    // Called first thing as part of callAnApi
    case FETCHING: 
      return {
        ...state,
        loading: true
      }
    case FETCH_SUCESS:
      return {
        ...state,
        data: action.payload,
        loading: false
      }
    case FETCH_FAILED:
      return {
        ...state,
        error: action.payload.error,
        loading: false
      }
    default:
      return state
  }
}


class AClassName extends Component {
  constructor(props){
    super(props);
  }

  componentWillMount() {
    this.props.callAnApi();
  }

  //assume in reducer your loading initialstate is false

  render() {

    this.props.loading && return <SomethingElse { ...this.props } />
    this.props.something && return <Redirect to={`/app/${this.props.something}`} />
  }
}

This flow has always worked for me

-1
votes

considering the conditional rendering,

for rendering, this.props.loading should be false and skipping the rendering, this.props.loading shoule be true.

You can simply merge the default initState when you want default values e.g.loading = true.

const initState = {
  loading: true,
  data: null,
  error: null
}

export function global(state = initState, action) {
  switch (action.type) {
    case FETCHING:
      return {
        {
          ...state
        },
        {
          ...initState
        }
      }

    case FETCH_SUCESS:
      return {
        ...state,
        ...initState,
        data: action.payload,
      }
    case FETCH_FAILED:
      return {
        ...state,
        ...initState,
        error: action.payload.error,
        loading: false
      }
    default:
      return { ...state,
        ...initState
      }
  }
}