【发布时间】: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