首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何指定高阶组件除了接受基组件的其余属性之外,还应该接受属性?

如何指定高阶组件除了接受基组件的其余属性之外,还应该接受属性?
EN

Stack Overflow用户
提问于 2019-11-27 11:10:51
回答 1查看 218关注 0票数 0

我正在尝试学习React / Redux在类型转换环境中的高级组件的用法。我有两个高阶组件:

component

  • withErrorListener:
  1. withId:为基本组件生成uniqueId属性,在redux存储上呈现来自基本组件请求的错误。基组件应该有从uniqueId高级组件创建的withId属性.

NewComponent = withErrorListener(withId(BaseComponent))

代码语言:javascript
复制
const PostsListWithId = withId(PostsListBase);
export const PostsListConnected = connector(withErrorListener(PostsListWithId));

我是按以下方式使用临时文件的:

代码语言:javascript
复制
import * as React from "react";
import { connect, ConnectedProps } from "react-redux";
import { Link } from "react-router-dom";
import { RootState } from "typesafe-actions";

import { Post as PostComponent } from "../components/Post";

import { allPostsAction, createPostsRequest } from "../features/posts/actions";
import { HocComponentProps } from "../higher-order-components/types";
import { Post } from "../features/posts/types";
import { withErrorListener } from "../higher-order-components/withErrorListener";
import { withId } from "../higher-order-components/componentId/withId";

type StateProps = {
  isLoading: boolean;
  posts: Post[];
};

/**
 * Redux dispatch and state mappings
 */
const dispatchProps = {
  fetchPosts: allPostsAction.request
};

const mapStateToProps = (state: RootState): StateProps => ({
  isLoading: state.posts.isLoadingPosts,
  posts: state.posts.posts
});

const connector = connect(
  mapStateToProps,
  dispatchProps
);

type ReduxProps = ConnectedProps<typeof connector>;

/**
 * Component property type definitions
 */
type Props = ReduxProps & HocComponentProps;

/**
 * CourseList component
 */
const PostsListBase = ({
  posts = [],
  uniqueId,
  fetchPosts,
  isLoading
}: Props): JSX.Element => {
  console.log(`PostListBase id :: ${uniqueId}`);

  // dispatch fetch posts action on mount
  React.useEffect(() => {
    console.log(
      `PostListBase dispatching PostsRequest action with id ${uniqueId}`
    );
    fetchPosts(createPostsRequest(uniqueId));
  }, [fetchPosts, uniqueId]);

  if (isLoading) {
    return (
      <>
        <p>Loading...</p>
        <Link to="/">Home</Link>
      </>
    );
  }

  return (
    <div style={{ marginTop: 20, padding: 30 }}>
      <Link to="/">Home</Link>
      <h2>List of post id's</h2>
      {
        <ul>
          {posts.map(element => (
            <li key={element.id}>
              <PostComponent post={element} />
            </li>
          ))}
        </ul>
      }
    </div>
  );
};

const PostsListWithId = withId(PostsListBase);
export const PostsListConnected = connector(withErrorListener(PostsListWithId));

/**
 * Argument of type 'typeof IdHoC' is not assignable to parameter of type 'ComponentType<ExpectedProps>'.
  Type 'typeof IdHoC' is not assignable to type 'ComponentClass<ExpectedProps, any>'.
    Types of parameters 'hocprops' and 'props' are incompatible.
      Type 'ExpectedProps' is missing the following properties from type 'Pick<Props, "posts" | "fetchPosts" | "isLoading">': posts, fetchPosts, isLoadingts(2345)
 */

但是,我收到下列打字本编译错误:

代码语言:javascript
复制
Argument of type 'typeof IdHoC' is not assignable to parameter of type 'ComponentType<ExpectedProps>'.
  Type 'typeof IdHoC' is not assignable to type 'ComponentClass<ExpectedProps, any>'.
    Types of parameters 'hocprops' and 'props' are incompatible.
      Type 'ExpectedProps' is missing the following properties from type 'Pick<Props, "posts" | "fetchPosts" | "isLoading">': posts, fetchPosts, isLoadingts(2345)

如何正确地指定withErrorListener高阶组件应该接受除基组件中的其余属性之外还包含uniqueId属性的类型,在这种情况下:{posts、fetchPosts和isLoading}?

我目前正试图在代码中这样做:

代码语言:javascript
复制
type ExpectedProps = { uniqueId: string };
export const withErrorListener = <BaseProps extends ExpectedProps>(
  BaseComponent: React.ComponentType<BaseProps>
) => {....}

我在这里创建了一个codesandbox项目,包括高阶组件的源代码:

我想我已经解决了这个问题。下面的注释中提出了其中一个问题,涉及到withId返回一个包装组件(不包括注入id属性)。已删除此约束并接受该注释作为解决方案。另一个问题是,消费组件需要连接到redux存储的属性才能接收来自Api的获取状态。更新较高构成部分的使用者如下:

代码语言:javascript
复制
// ensure consuming component is connected to redux store to fulfill it's other property requirements
const PostsListConnectedWithId = connector(withId(PostsListBase));
export const PostsListWithErrorListener = withErrorListener(PostsListConnectedWithId);

打字脚本

相对于:

代码语言:javascript
复制
const PostsListWithId = withId(PostsListBase);
export const PostsListWithErrorListener = connector(withErrorListener(PostsListWithId));

包括指向叉状沙箱的链接,以防其他人遇到类似的问题:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-27 11:57:49

我已经看过你的CodeSandbox样本了,我真的不明白你需要什么。

因此,在您的代码中,withId HoC接受一个基本的comp (在您的例子中是PostsListBase ),并向它注入uniqueId支持,然后返回一个包装的comp,不再需要 uniqueId作为支持输入,因为它已经从withId获得了它。

然后,将不再需要uniqueIduniqueId放在withErrorListener(WrappedPostsListBase)中。

下面是令人困惑的部分,您指定withErrorListener只接受需要的基本comp输入,这是一个uniqueId支柱。看到冲突了吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59068864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档