useParams data as an state object key in useSelector with TS

huangapple go评论117阅读模式
英文:

useParams data as an state object key in useSelector with TS

问题

我需要使用从useParams获取的键来访问状态数据。像这样:

  1. export const MainPageSection = (props: MainPageSectionPropsType) => {
  2. const params = useParams();
  3. const currentSection = params.section;
  4. const excursions: ExcursionsCollectionResponseType = useSelector((state: AppRootStateType) => state[currentSection]);
  5. ...
  6. }

出现了错误TS2538:类型'undefined'不能用作索引类型。但是我不能在这里使用条件语句,所以我将这个组件包装在一个容器中,在那里检查params的值并将其传递给我的组件。像这样:

  1. export const MainPageSection = () => {
  2. const params = useParams();
  3. const currentSection = params.section;
  4. if (!currentSection) return;
  5. return <MainPageSectionChild param={currentSection} title={'Title'}/>;
  6. }
  7. export const MainPageSectionChild = (props: MainPageSectionPropsType) => {
  8. const excursions: ExcursionsCollectionResponseType = useSelector((state: AppRootStateType) => state[props.param]);
  9. const excursion: ExcursionCollectionResponseItemType = excursions[0];
  10. }

但现在又出现了另一个错误:
TS7053:元素隐式具有'any'类型,因为类型为'string'的表达式不能用于类型'EmptyObject & { excursions: ExcursionsCollectionResponseType; tours: ToursCollectionResponseType; }'的索引。在类型'EmptyObject & { excursions: ExcursionsCollectionResponseType; tours: ToursCollectionResponseType; }'上找不到具有类型'string'的参数的索引签名。

有人可以给个提示如何解决吗?谢谢。

英文:

I need to access the state data using a key that I'm getting from useParams.
Like this:

  1. export const MainPageSection = (props:MainPageSectionPropsType) =&gt; {
  2. const params = useParams();
  3. const currentSection = params.section
  4. const excursions:ExcursionsCollectionResponseType =
  5. useSelector((state:AppRootStateType)=&gt; state[currentSection])
  6. ...
  7. }

Got an error TS2538: Type 'undefined' cannot be used as an index type. But I can't use conditionals here, so I wrapped this component in a container to get check for params value there and pass it to my component. Like that:

  1. export const MainPageSection = () =&gt; {
  2. const params = useParams();
  3. const currentSection = params.section
  4. if (!currentSection) return
  5. return &lt;MainPageSectionChild param={currentSection} title={&#39;Title&#39;}/&gt;
  6. }
  7. export const MainPageSectionChild = (props:MainPageSectionPropsType) =&gt; {
  8. const excursions:ExcursionsCollectionResponseType = useSelector((state:AppRootStateType)=&gt; state[props.param])
  9. const excursion:ExcursionCollectionResponseItemType = excursions[0]

But now there's another error:
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'EmptyObject & { excursions: ExcursionsCollectionResponseType; tours: ToursCollectionResponseType; }'.   No index signature with a parameter of type 'string' was found on type 'EmptyObject & { excursions: ExcursionsCollectionResponseType; tours: ToursCollectionResponseType; }'.

Can anybody give a clue on how to solve it? Thanks.

答案1

得分: 1

如果我理解你的问题正确的话,你之所以这样做是因为你无法有条件地调用useSelector。但是你可以在每次组件渲染时调用它,只是要使用一个有条件的值:

  1. export const MainPageSection = (props:MainPageSectionPropsType) => {
  2. const params = useParams();
  3. const currentSection = params.section
  4. const excursions:ExcursionsCollectionResponseType | undefined =
  5. useSelector(currentSection ? (state:AppRootStateType)=> state[currentSection] : () => {})
  6. }

在第一次渲染时,当currentSectionundefined时,excursions将是undefined,因为useSelector是用一个空函数() => {}调用的。之后,当组件重新渲染并且currentSection获得了预期的值时,useSelector将使用(state:AppRootStateType)=> state[currentSection]进行调用,excursions应该接收到预期的数据。

现在你只需要处理一下:

  1. //...
  2. if(!excursions) return null
  3. return (
  4. <>
  5. //...
  6. </>
  7. )
英文:

If I understood your problem, you are doing this because you cannot call useSelector conditionally.<br> However you can call it on every component render as you have to do but with a conditional value:

  1. export const MainPageSection = (props:MainPageSectionPropsType) =&gt; {
  2. const params = useParams();
  3. const currentSection = params.section
  4. const excursions:ExcursionsCollectionResponseType | undefined =
  5. useSelector(currentSection ? (state:AppRootStateType)=&gt; state[currentSection] : () =&gt; {})
  6. }

During the first render when currentSection is undefined, excursions will be undefined since useSelector is called with an empty function () =&gt; {}, after that when the component rerenders and currentSection get the expected value, useSelector is called with (state:AppRootStateType)=&gt; state[currentSection] and excursions should recive the expected data.

Now you just have to handle that

  1. //...
  2. if(!excursions) return null
  3. return (
  4. &lt;&gt;
  5. //...
  6. &lt;/&gt;
  7. )

答案2

得分: 0

你能展示一下你是如何配置 store 并定义 AppRootStateType 类型的吗?如果你按照 这个指南 正确操作的话,你应该有一个 useAppSelector 函数,它不需要你写 (state: Type) =&gt; ... 这样的语法。不管怎样,我认为 store 的配置可能有些问题。

英文:

Can you show me how you configured the store and defined the AppRootStateType type ? If you followed this guide correctly, you would have a useAppSelector, that does not require you to do (state: Type) =&gt; ... . Anyway, I think something is not right in the configuration of the store.

huangapple
  • 本文由 发表于 2023年8月8日 20:23:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76859528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定