首页 > 解决方案 > 操作和状态显示在控制台上,但在带有钩子的应用程序上未定义

问题描述

我正在尝试做一个从 API 读取并在屏幕上打印 itens 列表但也不工作的应用程序,我被困在这 5 天。

我在这里用 Fake API 做了一个代码框:https ://codesandbox.io/s/heuristic-wright-on220我在下面解释了通过代码的问题

首先,我在 index.js 上创建了我的商店

const store = createStore(reducer, applyMiddleware(...middleware));

const App = () => {
  return (
    <Router>
      <Switch>
        <Route path="/" exact component={Dashboard} />
        <Route component={NoMatchRoute} />
      </Switch>
    </Router>
  );
};

我在 metrics.js 上创建了我的状态

 export type MetricState = {
  metrics: IMetric[];
};

最后在 Dashboard.tsx 上,我通过使用“fetchMetrics”进行 api 调用来更新状态,从而在屏幕上打印:

const catalog = useSelector<RootState, MetricState>(
    (state) => state.metricsList
  );

  const dispatch = useDispatch();

  const classes = useStyles();
  useEffect(() => {
    dispatch(appReducer.actionCreators.fetchMetrics());
  }, []);

这里 fetchMetrics 的定义

   export function fetchMetrics() {
      const action = {
        type: ACTION_TYPES.FETCH_METRICS,
         payload: []
       };
      return fetchMetricsCall(action);
    }
    const fetchMetricsCall = (action) => async (dispatch) => {
      try {
        const res = await axios.get("/api/foo");
        dispatch({
          type: action.type,
          payload: res.data //contains the data to be passed to reducer
        });
      } catch (e) {
        dispatch({
          type: ACTION_TYPES.FAILURE,
          payload: console.log(e) //TODO: fix return type
        });
      }
    };
    
    export default {
      fetchMetrics
    };

在 index.js 我创建状态并连接提供者

const store = createStore(
    rootReducer,
    applyMiddleware(...middleware)
)

const App = () => {

  return (
    <Router>
      <Switch>
        <Route path="/" exact component={Dashboard} />
        <Route component={NoMatchRoute} />
      </Switch>
    </Router>
  );
};

这是我的减速器:

const initialState: MetricState = {
  metrics: []
};

const fetchMetrics = (
  state = initialState,
  action: MetricAction
): MetricState => {
  switch (action.type) {
    case ACTION_TYPES.FETCH_METRICS:
      return {
        ...state,
        metrics: action.payload
      };
    case ACTION_TYPES.CHOOSE_METRIC:
      return {
        ...state,
        metrics: action.payload
      };
    default:
      return {
        ...state
      };
  }
};

const rootReducer = combineReducers({
  fetchMetrics
});

export default rootReducer;

我的问题是我无法让它工作。我已经阅读了很多关于 stackoverflow 问题和教程的内容,但我找不到我的错误。有人有想法吗?在图像上可以看到数据是从真实的 API 中获取的,但没有显示在屏幕上。

谢谢! 在此处输入图像描述

标签: reactjsreact-reduxreact-hooks

解决方案


它看起来并不state.metricsList实际存在于状态内部,而Dashboard组件内部是(state) => state.metricsList. 您的状态只有fetchMetrics.metricscombineReducer将使用减速器名称的键将对象添加到状态中)

所以现在,您的状态结构如下所示:

state: { 
  fetchMetrics: { 
    metrics: [] 
  }
}

我认为你需要改变的主要两件事是:

指标.ts

export type RootState = {
  fetchMetrics: MetricState;
};

仪表板.tsx

const catalog = useSelector<RootState, MetricState>(
  (state) => state.fetchMetrics
);

代码沙箱metrics中有一些奇怪的 HTML 错误,如果我的答案不起作用,请告诉我。


推荐阅读