【问题标题】:React Hooks: useEffect, useReducer, createContext and localStorage; TypeError: Cannot read property of undefinedReact Hooks:useEffect、useReducer、createContext 和 localStorage; TypeError:无法读取未定义的属性
【发布时间】:2021-01-11 19:26:31
【问题描述】:

我在我的地图应用程序中使用本地存储来进行一些持久存储;还使用 React.createContext 和 useReducer 在组件之间共享和更新状态。

本地存储中的状态,以及控制台中的应用程序中的状态正在更新和呈现,即哈希生成的 id,来自 Cloudinary 的图像路径。

但是当我点击地图添加标记时,我得到:

TypeError: 无法读取未定义的属性“标记”

这很奇怪,因为我在控制台和本地存储中看到的内容。

我的想法是我的接线错误。

我的 UserContext 组件:

var initialState = {
  avatar: '/static/uploads/profile-avatars/placeholder.jpg',
  id: null,
  isRoutingVisible: false,
  removeRoutingMachine: false,
  isLengthOfMarkersLessThanTwo: true,
  markers: [],
  currentMap: {}
};

var UserContext = React.createContext();

function UserProvider({ children }) {
  function userReducer(state, { type, payload }) {

    switch (type) {
      case 'setUserId': {
        return { ...state, ...{ id: payload.id } };
        }

      case 'setAvatar': {
        return {
          ...state,
          ...{ avatar: payload.avatar }
        };
      }

      case 'setIsRoutingVisible': {
        return {
          ...state,
          ...{ isRoutingVisible: payload.isRoutingVisible }
        };
      }

      case 'isLengthOfMarkersLessThanTwoFalse': {
        return {
          ...state,
          ...{
            isLengthOfMarkersLessThanTwo: payload.isLengthOfMarkersLessThanTwo
          }
        };
       
      }

      case 'addMarker': {
        user.isLengthOfMarkersLessThanTwo
          ? {
              ...state,
              markers: user.markers.concat(payload.marker)
            }
          : null;
        break;
      }
   
      default: {
        throw new Error(`Unhandled action type: ${type}`);
      }
    }
  }

  const [user, setUser] = useState(() => getLocalStorage('user', initialState));
  var [state, dispatch] = useReducer(userReducer, user);

  const [isAvatarUploading, setIsAvatarUploading] = useState(true);

  useEffect(() => {
    setLocalStorage('user', state);
  }, [state]);

  useEffect(() => {
    console.log('state', state);
    if (state.markers.length === 2) {
      dispatch({
        type: 'isLengthOfMarkersLessThanTwoFalse',
        payload: { isLengthOfMarkersLessThanTwo: false }
      });
    }
  }, [JSON.stringify(state.markers)]);

  useEffect(() => {
    console.log('state', state);

    if (state.id) {
      getUserAvatar()
        .then(userAvatar => {
          console.log('userAvatar ', userAvatar);
          setIsAvatarUploading(false);
          dispatch({
            type: 'setAvatar',
            payload: { avatar: userAvatar }
          });
        })
        .catch(err => console.log('error thrown from getUserAvatar', err));
    } else {
      console.log('No user yet!');
    }
  }, [state.id]);

  return (
    <UserContext.Provider
      value={{
        userId: state.id,

        userAvatar: state.avatar,

        dispatch: dispatch,

        isAvatarUploading: state.isAvatarUploading,

        userImages: state.images,

        userMarkers: state.markers,

        userMap: state.currentMap,

        removeRoutingMachine: state.removeRoutingMachine,

        isRoutingVisibile: state.isRoutingVisible
      }}
    >
      {children}
    </UserContext.Provider>
  );
}

export default UserContext;

export { UserProvider };

我认为我需要一个自定义挂钩,用于传递旧状态并使用它来观察更改和更新它。

  var newUserState = initialState => {
    const [state, setState] = useState(initialState);
    var setter = useCallback(() => setState(state => !state), [setState]);
    return [state, setter];
  };


  var [newUserState, setter] = newUserState(state)

任何帮助将不胜感激!

【问题讨论】:

    标签: reactjs local-storage use-effect use-context use-reducer


    【解决方案1】:

    在您的 addMarker 情况下,您可能希望访问局部的 state 变量而不是全局的 user

    另外,根据我对this other question's answer 的理解,您宁愿在组件之外定义减速器,因为当您重新定义减速器功能时,React 会触发一些不需要的更新。

    这些是否能解决您的问题,我不能说...

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 2023-04-01
      • 1970-01-01
      • 2021-09-24
      • 2020-07-10
      • 2019-07-07
      • 2021-03-10
      • 2020-02-10
      • 2021-04-17
      相关资源
      最近更新 更多