在 react-admin 中实现 BackButton

implement BackButton in react-admin

我需要在 react-admin 中实现 <BackButton />,例如,当我打开 show 资源页面时,我需要能够返回到 list 页面。

你能指导我实现这个吗? 我不熟悉 react-admin 路由机制。 现在我在 edit 表单 actions props:

中使用这个组件
const MyActions = ({ basePath, data, resource }) => (
    <CardActions>
        <ShowButton basePath={basePath} record={data} />
        <CloneButton basePath={basePath} record={data} />
        {/* Need <BackButton /> here */}
    </CardActions>
);

export const BookEdit = (props) => (
    <Edit actions={<MyActions />} {...props}>
        <SimpleForm>
            ...
        </SimpleForm>
    </Edit>
);

您可以使用 react-router-redux's goBack() function 来实现。

例如,您的按钮组件将如下所示:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import Button from '@material-ui/core/Button';
import { goBack } from 'react-router-redux';

class BackButton extends Component {
    handleClick = () => {
        this.props.goBack();
    };

    render() {
        return <Button variant="contained" color="primary" onClick={this.handleClick}>Go Back</Button>;
    }
}

export default connect(null, {
    goBack,
})(BackButton);

现在在您的 CardActions 中使用该按钮组件。

您可以从 an example which uses react-router-redux's push() function in a similar way from the official docs 获得帮助。

完整代码如下。

//BackButton.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import compose from 'recompose/compose';
import { withStyles, createStyles } from '@material-ui/core/styles';
import { translate } from 'ra-core';
import Button from '@material-ui/core/Button';
import ArrowBack from '@material-ui/icons/ArrowBack';
import classnames from 'classnames';
import { fade } from '@material-ui/core/styles/colorManipulator';

const styles = theme =>
    createStyles({
        deleteButton: {
            color: theme.palette.error.main,
            '&:hover': {
                backgroundColor: fade(theme.palette.error.main, 0.12),
                // Reset on mouse devices
                '@media (hover: none)': {
                    backgroundColor: 'transparent',
                },
            },
        },
    });

const sanitizeRestProps = ({
    basePath,
    className,
    classes,
    label,
    invalid,
    variant,
    translate,
    handleSubmit,
    handleSubmitWithRedirect,
    submitOnEnter,
    record,
    redirect,
    resource,
    locale,
    ...rest
}) => rest;

class BackButton extends Component {
  static contextTypes = {
    router: () => true, // replace with PropTypes.object if you use them
  }

  static propTypes = {
          label: PropTypes.string,
          refreshView: PropTypes.func.isRequired,
          icon: PropTypes.element,
      };

  static defaultProps = {
      label: 'ra.action.back',
      icon: <ArrowBack />,
  };

  render() {
    const {
                className,
                classes = {},
                invalid,
                label = 'ra.action.back',
                pristine,
                redirect,
                saving,
                submitOnEnter,
                translate,
                icon,
                onClick,
                ...rest
            } = this.props;
    return (
      <Button
            onClick={this.context.router.history.goBack}
            label={label}
            className={classnames(
                'ra-back-button',
                classes.backButton,
                className
            )}
            key="button"
            {...sanitizeRestProps(rest)}>
          {icon} {label && translate(label, { _: label })}
      </Button>
    )
  }
}

const enhance = compose(
    withStyles(styles),
    translate
);

export default enhance(BackButton);
//Toolbar.js

import React from 'react';
import {
    Toolbar,
    SaveButton,
    DeleteButton,
} from 'react-admin';

import { withStyles } from '@material-ui/core';
import BackButton from './BackButton'

const toolbarStyles = {
    toolbar: {
        display: 'flex',
        justifyContent: 'space-between',
    },
};

export const CustomEditToolbar = withStyles(toolbarStyles)(props => (
    <Toolbar {...props}>
        <SaveButton/>
        <DeleteButton/>
        <BackButton/>
    </Toolbar>
));

export const CustomCreateToolbar = withStyles(toolbarStyles)(props => (
    <Toolbar {...props}>
        <SaveButton/>
        <BackButton/>
    </Toolbar>
));

创建后退按钮。这个将传递 props 和 children(文本)并直接使用 react-router,我认为这更有意义并使您的代码简单。

// BackButton.js

import React from 'react'
import Button from '@material-ui/core/Button'
import { withRouter } from 'react-router'

const BackButton = ({ history: { goBack }, children, ...props }) => (
  <Button {...props} onClick={goBack}>
    {children}
  </Button>
)

export default withRouter(BackButton)

用法示例:

import { Toolbar, SaveButton } from 'react-admin'
import BackButton from './BackButton'

const SomeToolbar = props => (
  <Toolbar {...props}>
    <SaveButton />
    <BackButton
      variant='outlined'
      color='secondary'
      style={{ marginLeft: '1rem' }}
    >
      Cancel
    </BackButton>
  </Toolbar>
)