我的应用程序上有一个项目列表,我正试图在单击时为每个项目创建一个详细信息页面。此外,我不知道如何使用useState和typescript来实现它,我可以只使用componentDidMount来实现,这不是我的目标。
关于我的状态,称为MetricState
,我有"metrics"
,我在一些地方看到我也应该在我的状态中添加"selectedMetric"
。我认为这是一个奇怪的解决方案,因为我只想能够用";在处于状态的度量列表上选择id为x的度量
这是代码沙盒,当你点击";细节";按钮,您将看到它没有打印来自状态的所选度量的名称:https://codesandbox.io/s/react-listing-forked-6sd99
这是我的州:
export type MetricState = {
metrics: IMetric[];
};
调度调用的我的actionCreators.js文件
export function fetchMetric(catalog, metricId) {
const action = {
type: ACTION_TYPES.CHOOSE_METRIC,
payload: []
};
return fetchMetricCall(action, catalog, metricId);
}
const fetchMetricCall = (action, catalog, metricId) => async (dispatch) => {
dispatch({
type: action.type,
payload: { metrics: [catalog.metrics.filter((x) => x.name === metricId)] } //contains the data to be passed to reducer
});
};
最后是MetricsDetail.tsx页面,我试图用来自路由参数的id过滤所选项目:
const metricId = props.match.params.metricId;
const catalog = useSelector<RootState, MetricState>(
(state) => state.fetchMetrics
);
const selectedMetric: IMetric = {
name: "",
owner: { team: "" }
};
const dispatch = useDispatch();
useEffect(() => {
dispatch(appReducer.actionCreators.fetchMetric(catalog, metricId));
}, []);
在我的状态,称为MetricState上,我有"度量";我在一些地方看到我应该加上一个";selectedMetric";我的州也一样。我认为这是一个奇怪的解决方案,因为我只想能够用";在处于状态的度量列表上选择id为x的度量;。
我同意你的看法。metricId
通过props
来自URL,因此它不需要也处于该状态。你想要一个";真理的单一来源";对于每条数据。
为了使用这种设计模式,您的Redux商店需要能够:
- 根据其id获取并存储单个度量
- 根据id从存储中选择一个选择度量
我通常发现使用键控对象状态(Record<string, IMetric>
(更容易,但array
也能工作。
你的组件应该是这样的:
const MetricDetailsPage: React.FC<MatchProps> = (props) => {
const metricId = props.match.params.metricId;
// just select the one metric that we want
// it might be undefined initially
const selectedMetric = useSelector<RootState, IMetric | undefined>(
(state) => state.fetchMetrics.metrics.find(metric => metric.name === metricId )
);
const dispatch = useDispatch();
useEffect(() => {
dispatch(appReducer.actionCreators.fetchMetric(metricId));
}, []);
return (
<div>
<Link to={`/`}>Go back to main page</Link>
Here should print the name of the selected metric:{" "}
<strong>{selectedMetric?.name}</strong>
</div>
);
};
export default MetricDetailsPage;
但是您应该重新操作您的动作创建者,这样您就不会在组件中选择整个catalog
,然后将其作为参数传递给动作创建者。