【问题标题】:Reactjs useReducer hook error ReferenceError: Cannot access 'reducer' before initializationReactjs useReducer钩子错误ReferenceError:初始化之前无法访问'reducer'
【发布时间】:2020-03-01 16:04:23
【问题描述】:

我正在通过阅读在线教程来学习 Reactjs 钩子。这是我的代码。我确信它可以改进。我收到了这个错误:-

ReferenceError: 在初始化之前无法访问“reducer”

    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]);

请告诉我如何改进此代码以及为什么会出现此错误?

【问题讨论】:

  • 在调用useReducer之前移动const reducer的声明
  • profileInitSate 相同

标签: reactjs react-hooks


【解决方案1】:

正如 Asyush 在评论部分指出的那样并对其进行解构以使其更清洁,其余部分看起来不错,尽管我建议将减速器保存在单独的文件中

      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]);

【讨论】:

  • 由于我正在学习reducer,将reducer移动到另一个文件意味着我制作了一个reducer.js,并在这个文件中包含了̧const profileInitSate =const reducer = (state, action) =>{。后来我import reducer from './reducer.js'。还是别的什么?
  • 是的,应该这样做,加上将profileInitSate 作为初始状态,如const reducer = (state=profileInitSate, action) =>{
  • 谢谢!我可以知道它会带来什么好处吗?为什么建议将 reducer 移到单独的文件中?
  • 可以说,如果以后你决定使用 Redux 之类的东西,你可能需要合并 Reducer,所以只导入 reducer 文件并合并它们会更有效,而不是必须使用包含其余内容的文件,或者即使您使用 ContextAPI 作为替代方法,也可以更清洁地拥有 3 个单独的文件:上下文、状态和减速器,从中您可以轻松理解流程
  • 感谢您的信息!所有这一切都超出了我的想象,因为我只是在触及 Reactjs 的表面。希望随着时间的推移,我会更加了解和理解 Reactjs 的高级主题。无论如何谢谢!
猜你喜欢
  • 2021-02-11
  • 1970-01-01
  • 2020-12-29
  • 2021-09-10
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多