Reactjs 使用useState和useEffect筛选处于状态的项目列表中的项目
我在我的应用程序上有一个项目列表,我正在尝试为每个项目创建一个详细信息页面。此外,我没有管理如何使用useState和useEffect使用typescript,我可以管理使用componentDidMount,这不是我的目标 在我的状态中,称为Reactjs 使用useState和useEffect筛选处于状态的项目列表中的项目,reactjs,typescript,react-redux,react-hooks,Reactjs,Typescript,React Redux,React Hooks,我在我的应用程序上有一个项目列表,我正在尝试为每个项目创建一个详细信息页面。此外,我没有管理如何使用useState和useEffect使用typescript,我可以管理使用componentDidMount,这不是我的目标 在我的状态中,称为MetricState,我有“metrics”,我在一些地方看到,我也应该在我的状态中添加一个“selectedMetric”。我认为这是一个奇怪的解决方案,因为我只想能够通过“在状态为的度量列表上选择id为x的度量”的操作来调用调度。 这是codesa
MetricState
,我有“metrics”
,我在一些地方看到,我也应该在我的状态中添加一个“selectedMetric”
。我认为这是一个奇怪的解决方案,因为我只想能够通过“在状态为的度量列表上选择id为x的度量”的操作来调用调度。
这是codesandbox,当您单击“详细信息”按钮时,您将看到它没有打印来自该州的所选度量的名称:
这是我的状态:
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
});
};
最后是MetricsDeatail.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));
}, []);
const metricId=props.match.params.metricId;
常量目录=使用选择器(
(state)=>state.fetchMetrics
);
常数selectedMetric:Metric={
姓名:“,
所有者:{团队:}
};
const dispatch=usedpatch();
useffect(()=>{
分派(appReducer.actionCreators.fetchMetric(catalog,metricId));
}, []);
在我的州,称为MetricState,我有“metrics”,我在一些地方看到,我也应该在我的州中添加一个“selectedMetric”。我认为这是一个奇怪的解决方案,因为我只希望能够通过“在状态为的度量列表上选择id为x的度量”的操作调用分派
我同意你的看法。metricId
通过props
来自URL,因此它也不需要处于该状态。您希望每个数据都有一个“单一的真相来源”
为了使用此设计模式,您的Redux商店需要能够:
- 根据度量的id获取并存储单个度量
- 根据存储的id从存储中选择度量
Record
)会更容易,但是数组也可以
您的组件应该如下所示:
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;
const MetricDetailsPage:React.FC=(道具)=>{
const metricId=props.match.params.metricId;
//只需选择我们想要的一个指标
//它最初可能没有定义
常量selectedMetric=useSelector(
(state)=>state.fetchMetrics.metrics.find(metric=>metric.name==metricId)
);
const dispatch=usedpatch();
useffect(()=>{
分派(appReducer.actionCreators.fetchMetric(metricId));
}, []);
返回(
返回主页
此处应打印所选度量的名称:{“”}
{selectedMetric?.name}
);
};
导出默认MetricDetailsPage;
但是您应该重新处理动作创建者,这样您就不会在组件中选择整个目录
,然后将其作为参数传递给动作创建者。嗨,琳达!谢谢你的帮助!我还有一个问题。在您的fakeApi上,您正在调用“数据”,但在我的例子中,我希望获取存储中的数据,因为我的数据不会在实际应用程序上被模拟。有什么建议吗?:)我可以使用您解释过的useSelector的一部分来检索度量,它可以工作,但我想分派一个操作,直接在actionCreators.js上对状态执行此筛选。如果存储中已经存在数据,则无需分派任何操作。其思想是,状态将存储所有以前加载的度量,因此如果从“/one”更改为“/two”,则不需要更改存储中的任何内容。但当您处理react路由器时,您需要使其能够独立加载每个页面。您不能指望在登录“/one”之前已加载完整列表。这就是为什么我认为会有一些API调用加载单个度量。