使用 CustomApp 时在路由中列出和编辑组件所需的道具

Required props for List and Edit components in route when using CustomApp

我正在尝试将自定义应用程序从 admin-on-rest 升级到 react-admin (v2.15)。在我发现 declareResources 操作是 registerResource 的 "replaced" 之后,大多数情况下似乎没问题,但我仍然在努力处理 List 和 Edit 组件路由定义,这些路由定义抱怨缺少必需的道具(与什么相比道具在 the custom app documentation).

中定义

如果我像这样定义一个 List 组件,它工作正常:

<Route exact path="/mystuffs" render={(routeProps) => <MystuffList hasCreate hasEdit hasShow={false} hasList resource="mystuffs" basePath="/mystuffs" {...routeProps} />} />

类似地,让编辑组件工作的唯一方法是像这样传递所需的道具:

<Route exact path="/mystuffs/:id" render={(routeProps) => <MystuffEdit resource="mystuffs" id={routeProps.match.params.id} basePath="/mystuffs" {...routeProps} />} />

但对我来说,定义所有这些道具似乎有点乏味(即 admin-on-rest 不需要)。这是正确的做法吗,还是我在这里遗漏了一些明显的东西,因为 the custom app documentation 没有指定所有必需的道具?

确实需要。我们在自定义应用程序方面还有很多工作要做,包括文档。

你可以帮助我们!您能解释一下为什么需要以这种方式使用 react-admin 吗?使用默认管理员有什么不可能?等等

谢谢!

我最终添加了一个自定义资源组件,它与 react-admin 中的资源非常相似。像这样:

    import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Switch, Route } from 'react-router-dom';


const RACustomResource = ({ resource, list, edit, create, show, path, children, ...rest }) => {
  const { computedMatch, ...options } = rest;

  const listResource = list ?
  (<Route
    exact
    path={path}
    render={(routeProps) => {
      const { staticContext, ...routeOpts } = routeProps;
      return React.createElement(list, {
        basePath: path || routeProps.match.url,
        resource,
        hasCreate: !!create,
        hasList: !!list,
        hasEdit: !!edit,
        hasShow: !!show,
        ...routeOpts,
        ...options,
      });
    }}
  />)
  : null;

  const createResource = create ?
    (<Route
      path={`${path}/create`}
      render={(routeProps) => {
        const { staticContext, ...routeOpts } = routeProps;
        return React.createElement(create, {
          basePath: path || routeProps.match.url,
          resource,
          hasList: !!list,
          hasShow: !!show,
          record: {},
          ...routeOpts,
          ...options,
        });
      }}
    />)
    : null;

  const editResource = edit ?
    (<Route
      exact
      path={`${path}/:id`}
      render={(routeProps) => {
        const { staticContext, ...routeOpts } = routeProps;
        return React.createElement(edit, {
          basePath: path || routeProps.match.url,
          resource,
          hasCreate: !!create,
          hasList: !!list,
          hasEdit: !!edit,
          hasShow: !!show,
          id: routeProps.match.params.id,
          ...routeOpts,
          ...options,
        });
      }}
    />)
    : null;

  const showResource = show ?
    (<Route
      exact
      path={`${path}/:id/show`}
      render={(routeProps) => {
        const { staticContext, ...routeOpts } = routeProps;
        return React.createElement(show, {
          basePath: path || routeProps.match.url,
          resource,
          hasCreate: !!create,
          hasList: !!list,
          hasEdit: !!edit,
          hasShow: !!show,
          id: routeProps.match.params.id,
          ...routeOpts,
          ...options,
        });
      }}
    />)
    : null;

  return (
    <Switch>
      {createResource}
      {showResource}
      {editResource}
      {listResource}
      {children}
    </Switch>
  );
};

RACustomResource.propTypes = {
  resource: PropTypes.string.isRequired,
  path: PropTypes.string,
  basePath: PropTypes.string,
  children: PropTypes.any,
  list: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  create: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  edit: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  show: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),

};

export default RACustomResource;


// used like this
// <RACustomResource path="/myresource" resource="myresource" list={MyResourceList} create={MyResourceCreate} edit={MyResourceEdit} />