masiboo
masiboo

Reputation: 4719

Reactjs useReducer hook error ReferenceError: Cannot access 'reducer' before initialization

I am learning Reactjs hoooks by reading online tutorials. Here is my code. I am sure it can be improved. I got this error:-

ReferenceError: Cannot access 'reducer' before initialization

    function ProfileForm(props) {
const form = useForm();
const {
  register,
  handleSubmit,
  errors,
  formState: { isSubmitting }
} = form;

const [profile, dispatch] = useReducer(reducer, profileInitSate)

const profileInitSate = {
  displayName: '',
  birthDate: '',
  height: 0,
}

const reducer = (state, action) =>{
    switch(action.type){
      case 'displayName' : 
        return {...state, displayName: action.value};

      case 'realName':
        return {...state, realName: action.value};

      case 'birthDate':
        return {...state, birthDate: action.value};          
      default:
        return state;          
    }  
}

useEffect(() => {
  if(props.location.state.profile){
      dispatch({type: 'dispalyName', 
      value: props.location.state.profile.displayName})
      dispatch({type: 'realName', 
      value: props.location.state.profile.realName})
      dispatch({type: 'birthDate', 
      value: props.location.state.profile.birthDate})
      dispatch({type: 'height', 
      value: props.location.state.profile.height})
  }

}, [profile]);

Please let me know how can I improve this code also why do I get this error?

Upvotes: 3

Views: 8865

Answers (1)

Abdullah Abid
Abdullah Abid

Reputation: 1661

As Asyush pointed out in the comment section and destructure it to keep it a cleaner, the rest seems good although i would suggest keeping the reducer in a seperate file

      function ProfileForm(props) {
    const form = useForm();
    const {
      register,
      handleSubmit,
      errors,
      formState: { isSubmitting }
    } = form;

    const profileInitSate = {
      displayName: '',
      birthDate: '',
      height: 0,
    }

    const reducer = (state, action) =>{
        switch(action.type){
          case 'displayName' : 
            return {...state, displayName: action.value};

          case 'realName':
            return {...state, realName: action.value};

          case 'birthDate':
            return {...state, birthDate: action.value};          
          default:
            return state;          
        }  
    }
// Change the name to avoid conflict because of destructure
   const [profileReducer, dispatch] = useReducer(reducer, profileInitSate)    

   let {profile} = props.location.state;

   let {displayName,realName,birthDate,height}=profile;

    useEffect(() => {
      if(props.location.state.profile){
          dispatch({type: 'dispalyName', 
          value: displayName})
          dispatch({type: 'realName', 
          value: realName})
          dispatch({type: 'birthDate', 
          value: birthDate})
          dispatch({type: 'height', 
          value: height})
       }

      }, [profileReducer]);

Upvotes: 4

Related Questions