useParams data as an state object key in useSelector with TS

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

useParams data as an state object key in useSelector with TS

问题

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

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

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

export const MainPageSection = () => {
    const params = useParams();
    const currentSection = params.section;
    if (!currentSection) return;
    return <MainPageSectionChild param={currentSection} title={'Title'}/>;
}

export const MainPageSectionChild = (props: MainPageSectionPropsType) => {
    const excursions: ExcursionsCollectionResponseType = useSelector((state: AppRootStateType) => state[props.param]);
    const excursion: ExcursionCollectionResponseItemType = excursions[0];
}

但现在又出现了另一个错误:
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:

export const MainPageSection = (props:MainPageSectionPropsType) =&gt; {
    const params = useParams();
    const currentSection = params.section
    const excursions:ExcursionsCollectionResponseType = 
    useSelector((state:AppRootStateType)=&gt; state[currentSection])
 ...
}

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:

export const MainPageSection = () =&gt; {
    const params = useParams();
    const currentSection = params.section
    if (!currentSection) return
    return &lt;MainPageSectionChild param={currentSection} title={&#39;Title&#39;}/&gt;
}
export const MainPageSectionChild = (props:MainPageSectionPropsType) =&gt; {
    const excursions:ExcursionsCollectionResponseType = useSelector((state:AppRootStateType)=&gt; state[props.param])
    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。但是你可以在每次组件渲染时调用它,只是要使用一个有条件的值:

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

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

现在你只需要处理一下:

//...

if(!excursions) return null
return (
 <>
  //...
 </>
)
英文:

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:

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

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

//...

if(!excursions) return null
return (
 &lt;&gt;
  //...
 &lt;/&gt;
)

答案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:

确定