user10715317
user10715317

Reputation:

Is this the right way to pass state to Redux action?

I'm using map to get the IDs from the array of objects in the render.

My code:

class AppliedCandidates extends Component {

  render() {
    const {
      appliedjobs
    } = this.props
    const {
      joblists
    } = this.props {
      joblists && joblists.map(joblist => {
        this.props.getAppliedJobs(joblist.id)
      })
    }
    return ( <
      div > {
        appliedjobs && appliedjobs.map(appliedjob => {
          return <ol >
            <
            li > {
              appliedjob.jobid
            } < /li> <
            li > {
              appliedjob.candidatephoneno
            } < /li> <
            /ol>
        })
      } <
      /div> 
    );
  }
}

const mapStateToProps = (state) => {
  console.log("state", state);
  return {
    joblists: state.getJobs.job,
    appliedjobs: state.getAppliedJobs.appliedjob
  }
}
const mapDispatchToProps = (dispatch) => {
  return {
    getAppliedJobs: (joblists) => dispatch(getAppliedJobs(joblists))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(AppliedCandidates);

and in the following code which is in the Redux action.js, if I uncomment the array variable "appliedjobs" the process goes into an endless loop. If I comment it out, I only get the last value.

var appliedjobs = []

const getAppliedJobs = (joblists) => {
  return (dispatch, getState, {
    getFirebase,
    getFirestore
  }) => {
    const firestore = getFirestore();
    firestore.collection('Jobs').doc(joblists).collection('AppliedJobs').where("jobid", "==", joblists)
      .get()
      .then((querySnapshot) => {
        if (querySnapshot.empty === true) {
          dispatch({
            type: 'GET_APPLIED_JOB_ERROR',
            joblists
          });

        } else {
          //appliedjobs =[] 
          querySnapshot.forEach(function(doc3) {
            appliedjobs.push({
              candidatephoneno: doc3.data().candidatephoneno,
              jobid: doc3.data().jobid,
            });
          });
          dispatch({
            type: 'GET_APPLIED_JOB',
            payload: appliedjobs
          });
        }
      })
  }
};

How to get the values?

Upvotes: 0

Views: 33

Answers (2)

mfakhrusy
mfakhrusy

Reputation: 1198

As Dor Shinar has said, don't call actions on the render function. Why? Because render function will be invoked every time any props/state is updated. So, if you call the action there, you'll keep re-rendering your page since you'll keep getting new updated props from the dispatched action.

I'm not sure about your action, since I never use firebase. But I guess it's some query calls.

class AppliedCandidates extends Component {
componentDidMount() {
  // here, the joblists props will get automatically updates from the dispatched redux action, dont mutate/change the props by yourself, change it via action.

  const { getAppliedJobs, joblists } = this.props;
  getAppliedJobs(joblists); // to be honest, why your action have the input of array and you put up id of individual array item? So I just put the entire joblists as the function parameter.

}

render() {
  const { appliedjobs } = this.props;

  if (appliedjobs.length === 0) {
    return null;
  }

  return ( // you can add more
    <ol>
      {appliedjobs.map(appliedjob => <li>{appliedjob.id}</li>)}
    </ol>
  )
}

const mapStateToProps = (state) => {
  return {
    joblists: state.getJobs.job,
    appliedjobs: state.getAppliedJobs.appliedjob
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    getAppliedJobs : (joblists) => dispatch(getAppliedJobs(joblists))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(AppliedCandidates);

Upvotes: 1

Dor Shinar
Dor Shinar

Reputation: 1512

You shouldn't dispatch actions in your render function. If you need to populate your data by dispatching actions to the store, you should do it in a lifecycle method, in this case I think componentDidUpdate fits best. from facebook's documentation:

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.

Use this as an opportunity to operate on the DOM when the component has been updated. This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed).

Upvotes: 1

Related Questions