reactjs - 如何取消选择 react 管理自定义批量操作按钮中的列表项

标签 reactjs material-ui react-admin

我有一个 react 管理项目,并为 ListView 实现了一个自定义按钮,传递到 bulkActionButtons 属性中,如此处文档所述:https://marmelab.com/react-admin/List.html#bulk-action-buttons

const BulkUserActions = props => (
  <MakeAdminButton {...props}/>
);

const UserList = props => (
  <List {...props} bulkActionButtons={<BulkUserActions/>}>
    <Datagrid rowClick="show">
      <TextField source="id"/>
      <EmailField source="email"/>
    </Datagrid>
  </List>
);

MakeAdminButton 处理单击并执行我需要的更新。谜题中缺少的部分是如何在操作完成后取消选择列表项。 props.selectedIds 受到保护,因此我无法在完成逻辑后简单地将其设置为空数组。

问题是如何取消设置 props.selectedIds 或其他在完成时取消选择列表项的方法。

const MakeAdminButton = withStyles(styles)(class MakeAdminButton extends React.Component {

  handleAction = () => {
    //does the stuff as required using this.props.selectedIds

    //what to return to unset this.props.selectedIds 
  };

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

最佳答案

React Admin 提供了执行此操作的方法。在 v3 上直接使用 useUnselectAll 或在 useMutation、useUpdateMany 和 useDataProvider Hook 的 onSuccess 回调上。在 v2 上,使用 withDataProvider 装饰器的 dataProvider 第四个参数,或者将自定义 redux 操作的 meta.onSuccess.unselectAll 设置为 true,或者自动使用 crudUpdateMany 或 Mutation 组件的 options 属性。

对于带有 crudUpdateMany 的 v2,转到 Mike Miller 答案。

工作示例:

https://codesandbox.io/s/exciting-firefly-dd1ni?file=/src/App.js

v3:

const UnselectAllButtonV3Hook = props => {
  const unselectAll = useUnselectAll();

  return (
    <Button
      onClick={() => {
        unselectAll(props.resource);
      }}
    >
      Unselect all with v3 hook
    </Button>
  );
};

https://marmelab.com/react-admin/doc/3.5/Actions.html#handling-side-effects-in-usedataprovider

useUpdateMany/useDataProvider/useMutation Hook ,onSuccess 回调从 useUnselectAll() 调用 unselectAll()

const MakeAdminButtonV3 = props => {
  const refresh = useRefresh();
  const unselectAll = useUnselectAll();

  const [makeAdmin, { loading }] = useUpdateMany(
    props.resource,
    props.selectedIds,
    { isAdmin: true },
    {
      onSuccess: () => {
        unselectAll(props.resource);
        refresh();
      }
    }
  );

  //OR

  const dataProvider = useDataProvider();

  const makeAdmin2 = () => {
    dataProvider.updateMany(
      props.resource,
      { ids: props.selectedIds, data: { isAdmin: true } },
      {
        onSuccess: () => {
          unselectAll(props.resource);
          refresh();
        }
      }
    );
  };

  //OR

  const [makeAdmin3, { loading3 }] = useMutation(
    {
      type: "updateMany",
      resource: props.resource,
      payload: { ids: props.selectedIds, data: { isAdmin: true } }
    },
    {
      onSuccess: () => {
        unselectAll(props.resource);
        refresh();
      }
    }
  );

  return (
    <Button onClick={makeAdmin3} disabled={loading3}>
      Make Admin with V3 dataProvider hooks
    </Button>
  );
};

https://marmelab.com/react-admin/doc/3.5/Actions.html#usemutation-hook

https://marmelab.com/react-admin/doc/3.5/Actions.html#usedataprovider-hook

https://marmelab.com/react-admin/doc/3.5/Actions.html#specialized-hooks

V2 示例也适用于 v3,但 Mutation 和 withDataProvider 是遗留的,直接使用 dataProvider 时会发生一些小变化,因为 v3 上的 dataProvider api 发生了变化。

https://marmelab.com/react-admin/doc/3.5/Actions.html#legacy-components-query-mutation-and-withdataprovider

v2:

withDataProvider:

const UnmakeAdminButtonWithWithDataProvider = withDataProvider(
  class extends React.Component {
    handleClick = () => {
      this.props.dataProvider(
        UPDATE_MANY,
        "users",
        { ids: this.props.selectedIds, data: { isAdmin: false } },
        { onSuccess: { unselectAll: true, refresh: true } }
      );
    };

    render() {
      return (
        <Button onClick={this.handleClick}>
          Unmake Admin with withDataProvider
        </Button>
      );
    }
  }
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#handling-side-effects

自定义 redux 操作:

import { connect } from 'react-redux';

const MAKE_ADMIN = "MAKE_ADMIN";

const makeAdmin = ids => ({
  type: MAKE_ADMIN,
  payload: { ids, data: { isAdmin: true } },
  meta: {
    fetch: UPDATE_MANY,
    resource: "users",
    onSuccess: { unselectAll: true, refresh: true }
  }
});

const MakeAdminButtonWithCustomAction = connect(
  null,
  { makeAdmin }
)(
  class extends React.Component {
    handleClick = () => {
      this.props.makeAdmin(this.props.selectedIds);
    };

    render() {
      return (
        <Button onClick={this.handleClick}>
          Make Admin With Custom Redux Action
        </Button>
      );
    }
  }
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#adding-side-effects-to-actions

突变成分:

const MakeAdminMutationV2 = props => (
  <Mutation
    type="updateMany" //{UPDATE_MANY}
    resource={props.resource}
    payload={{ ids: props.selectedIds, data: { isAdmin: true } }}
    options={{
      onSuccess: {
        unselectAll: true,
        refresh: true
      }
    }}
  >
    {approve => <Button onClick={approve}>Make admin with Mutation</Button>}
  </Mutation>
);

https://marmelab.com/react-admin/doc/2.9/Actions.html#query-and-mutation-components

关于reactjs - 如何取消选择 react 管理自定义批量操作按钮中的列表项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54075984/

相关文章:

javascript - useEffect 在循环中调用异步函数

node.js - 包 react 不满足它的 sibling

javascript - React Native 从另一个文件导入函数

datepicker - 如何在 Material UI 日期选择器中设置特定日期的样式

reactjs - React Admin - 如何隐藏操作按钮

javascript - 如何在 switch 语句(redux reducer)中更改数组的 ID?

reactjs - 选中后如何正确使用 MUISwitch "bar"颜色的主题覆盖?

reactjs - 如何在 React 中使用 Enzyme 或 React 测试库测试 Material-UI 的响应式 UI(例如隐藏、网格、断点)

react-admin - react-admin 中的多部分表单数据

admin-on-rest - React Admin - 如何使用像 abc/def 这样的嵌套路径调用 dataProvider