我正在尝试创建一个从 API 读取并在屏幕上打印 itens 列表但无法正常工作的应用程序。
我在这里用一个假 API 做了一个 codesandbox: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>
);
};
这是我的 reducer :
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;
我就是做不到。我已经阅读了很多 Stack Overflow 问题和教程,但我就是找不到我的错误。在图像上可以看到数据是从真实 API 获取的,但没有显示在屏幕上。
最佳答案
看起来state.metricsList
实际上并不存在于state内部,Dashboard
组件内部是(state) => state.metricsList
。您的状态只有 fetchMetrics.metrics
(combineReducer
将使用 reducer 名称的键将对象添加到状态)
所以现在,您的状态结构如下所示:
state: {
fetchMetrics: {
metrics: []
}
}
我认为您需要更改的主要两件事是:
指标.ts
export type RootState = {
fetchMetrics: MetricState;
};
仪表板.tsx
const catalog = useSelector<RootState, MetricState>(
(state) => state.fetchMetrics
);
在代码沙箱中 metrics
是一些奇怪的 HTML 错误,如果我的答案不起作用,请告诉我。
关于reactjs - 操作和状态显示在控制台上,但在带有 React Hook 的应用程序上未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67157362/