首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React : Error: userState必须在UserProvider中使用,而不是嵌套在提供者中?

React : Error: userState必须在UserProvider中使用,而不是嵌套在提供者中?
EN

Stack Overflow用户
提问于 2021-01-14 01:48:08
回答 1查看 2.1K关注 0票数 1

我是遵循这个伟大的图坦由肯特C.道兹关于使用反应上下文。

但是我实际上在提供程序中嵌套了这个组件,所以不确定我为什么要这样做。

错误: userState必须在UserProvider中使用

因此,也许我没有意识到创建一个函数的意义,尽管您应该如何使用提供程序.也许我没有正确地实现它?

这就是我的userContext设置:

代码语言:javascript
复制
import React, { useState, useEffect, useContext, useReducer } from 'react';

var initialState = {
 ...state...
};

var UserStateContext = React.createContext();
var UserContextDispatch = React.createContext();

function setLocalStorage(key, value) {
   ...function innards...
}

function getLocalStorage(key, initialValue) {
   ...function innards...
}

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 'addMarker': {
        user.isLengthOfMarkersLessThanTwo
          ? {
              ...state,
              markers: user.markers.concat(payload.marker)
            }
          : null;
        break;
      }
    
      case 'setMap': {
        return {
          ...state,
          currentMap: payload.curerntMap
        };
      }

      default: {
        throw new Error(`Unhandled action type: ${type}`);
      }
    }
  }

  const [user, setUser] = useState(() => getLocalStorage('user', initialState));

  var [state, dispatch] = useReducer(userReducer, user);

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

  return (
    <UserStateContext.Provider value={state}>
      <UserContextDispatch.Provider value={dispatch}>
        {children}
      </UserContextDispatch.Provider>
    </UserStateContext.Provider>
  );
}

function userState() {
  const context = React.useContext(UserStateContext);
  if (context === undefined) {
    throw new Error('userState must be used within a UserProvider');
  }
  return context;
}

function userDispatch() {
  const context = React.useContext(UserContextDispatch);
  if (context === undefined) {
    throw new Error('userDispatch must be used within a UserProvider');
  }
  return context;
}

export { UserProvider, userState, userDispatch };

错误指向我的Map组件,它将statedispatch道具从UserContext传递给作为类组件的路由组件。

代码语言:javascript
复制
import React, { useState, useContext, useEffect, useRef, useCallback } from 'react';
import { Button } from 'semantic-ui-react';

import L from 'leaflet';
import * as ELG from 'esri-leaflet-geocoder';
import { Map } from 'react-leaflet';
import { Dimmer, Loader } from 'semantic-ui-react';

import Routing from '../RoutingMachine/RoutingMachine.jsx';
import { userState, userDispatch } from '../Context/UserContext.jsx';

import UIContext from '../Context/UIContext.jsx';

import { stringify } from 'flatted';

export default function MyMap({}) {
  var [zoom, setZoom] = useState(18);
  var [animate, setAnimate] = useState(false);
  var [userLocation, setUserLocation] = useState(null);

  var mapRef = useRef();

  console.log('userState() ', userState());
  var {
    avatar,
    currentMap,
    id,
    isLengthOfMarkersLessThanTwo,
    isRoutingVisible,
    markers,
    removeRoutingMachine
  } = userState();

  var dispatch = userDispatch();

  var { isMobile, isDesktop } = useContext(UIContext);

  useEffect(() => {
    if (isRoutingVisible === false) {
      dispatch({
        type: 'setIsRoutingVisible',
        payload: {
          isRoutingVisible: true
        }
      });
    }
  });

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

  return (
    <Map
      animate={animate}
      onLocationFound={handleOnLocationFound}
      zoom={zoom}
      ref={mapRef}
    >
       
      {isRoutingVisible && (
        <Routing
          markers={markers}
          dispatch={dispatch}
          removeRoutingMachine={removeRoutingMachine}
          map={currentMap}
          userLocation={userLocation}
          isMobile={isMobile}
          isDesktop={isDesktop}
        />
      )}
    </Map>
  );
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-30 14:03:48

问题似乎在于我将state & dispatch值传递给每个提供者的方式:

代码语言:javascript
复制
 return (
    <UserStateContext.Provider value={state}>
      <UserContextDispatch.Provider value={dispatch}>
        {children}
      </UserContextDispatch.Provider>
    </UserStateContext.Provider>
  );

我通过传递一个值为:value={{ key: value }}的对象来使它工作

所以我们应该这样做:

代码语言:javascript
复制
return (
    <UserStateContext.Provider value={{ state: state }}>
      <UserContextDispatch.Provider value={{ dispatch: dispatch }}>
        {children}
      </UserContextDispatch.Provider>
    </UserStateContext.Provider>
  );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65712271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档