简体   繁体   English

使用 React 从表中删除项目后重新加载表

[英]Reload table after deleting an item from it with React

Using React.Js, I created a delete function to delete an item from a table.使用 React.Js,我创建了一个删除函数来从表中删除一个项目。 the delete is working fine but what I want to do is that after deleting I want the tables to be dynamically updated to show only the items left.删除工作正常,但我想要做的是删除后我希望表格动态更新以仅显示剩余的项目。 Now after the delete I have to refresh manually the page or go to another page and comeback to see the items left after the delete现在删除后我必须手动刷新页面或转到另一个页面并回来查看删除后留下的项目

This is the code built so far :这是迄今为止构建的代码:

import React, { Component } from "react";
import { Card, Button, Select,/*  message, */ Form, Tooltip } from "antd";
import extraitMP3 from "./data";
import { arrayMove, SortableHandle } from "react-sortable-hoc";
import ContainerHeader from "components/ContainerHeader/index";
import { getExtraitMp3, hideMessageUpdate, showUpdateLoader, updateMp3Visibilite } from "appRedux/actions/Comedien";
import { deleteMp3Request } from "../../../appRedux/services/extraitMp3Service"
import { connect } from "react-redux";
import { NotificationContainer, NotificationManager } from "react-notifications";
import { userSignOut } from "appRedux/actions/Auth";
import { displayIcon } from '../../../util/Icon.js';
import CircularProgress from "components/CircularProgress";
import { Modal } from "antd";

const extraitMP32 = [extraitMP3];
const confirm = Modal.confirm;
const Option = Select.Option;

const DragHandle = SortableHandle(() =>
  <span className="gx-draggable-icon gx-pt-2">
    <i className="icon icon-menu" style={{ fontSize: 25 }} />
  </span>);

class ListExtrait extends Component {

  onSortEnd = ({ oldIndex, newIndex }) => {
    this.setState({
      extraitMP3: arrayMove(this.state.extraitMP3, oldIndex, newIndex),

    });
  };

  constructor() {
    super();
    this.state = {
      extraitMP3: extraitMP32[0],
      nombreMP3: {
        rechercheExtraits: 0,
        recherchePossible: 0,
        extraitFiche: 0,
        extraitFichePossible: '',
        extraitArchives: 0,
        extraitArchivesPossible: '',
      },
      loader: false,

    }
  }

  componentDidMount() {
    this.props.getExtraitMp3();
  }

  componentDidUpdate() {
  }

  static getDerivedStateFromProps(nextProps, prevState,/* nextProps2,prevState2 */) {
    if (nextProps.extraitMP3 !== prevState.extraitMP3 && nextProps.extraitMP3) {
      return { extraitMP3: nextProps.extraitMP3 };
    }
    else return null;
  }
  showDeleteConfirmation(value, id, index, thisHandler) {
    confirm({
      title: 'Voulez vous supprimer cette audio ?',
      content: '',
      okText: 'Oui, je confirme',
      okType: 'danger',
      cancelText: 'Non',
      onOk() {
        deleteMp3Request(id);
        const { extraitMP3 } = thisHandler.state;
        Object.keys(extraitMP3).splice(index, 1);
        NotificationManager.success("le fichier audio est supprimé avec succès !", "");
      },
      onCancel() {
      },
    });
  }

  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {

      if (!err) {
        this.props.showUpdateLoader();
        this.props.updateMp3Visibilite(values);
      }
    });
  };

  render() {

    const { loader, extraitMP3 } = this.state;
    const selectOptions = new Map([
      [1, "Visible dans la recherche et sur ma fiche"],
      [2, "Visible sur ma fiche uniquement"],
      [3, "Masqué"],
    ]);
    console.log('extraitMP3', extraitMP3)


    function handleChangeSelect(value) {
      console.log(`selected ${value}`);
    }

    return (
      <div>
        {loader ? <CircularProgress className="gx-loader-400" /> : Object.keys(extraitMP3).map((ids, index) => {
          return (
            <Card>

              <li key={ids}>
                <Card styleName="gx-card-list icon icon-data-display gx-mr-2 gx-text-blue gx-fs-xl">
                  <div className="gx-media-body">
                    {extraitMP3[ids].Typenom}
                    &nbsp;
                  {extraitMP3[ids].TypeIcon != null &&
                      displayIcon(extraitMP3[ids].TypeIcon)
                    }
                  </div>

                  {Object.keys(extraitMP3[ids].TypeMp3List).map(idJson => {
                    return (
                      <div className="gx-main-content gx-mb-4">
                        <ContainerHeader match={this.props.match} />
                        <div className="gx-contact-item gx-dragndrop-item">

                          <DragHandle />

                          <div className="gx-col gx-job-title ">
                            {extraitMP3[ids].TypeMp3List[idJson].intitule}
                          </div>

                          {extraitMP3[ids].TypeMp3List[idJson].interpretation1Icon !== '' &&
                            <Tooltip title={extraitMP3[ids].TypeMp3List[idJson].interpretation1Nom}>
                              {displayIcon(extraitMP3[ids].TypeMp3List[idJson].interpretation1Icon)}
                            </Tooltip>
                          }

                          {extraitMP3[ids].TypeMp3List[idJson].interpretation2Icon !== '' &&
                            <Tooltip title={extraitMP3[ids].TypeMp3List[idJson].interpretation2Nom}>
                              {displayIcon(extraitMP3[ids].TypeMp3List[idJson].interpretation2Icon)}
                            </Tooltip>
                          }

                          {extraitMP3[ids].TypeMp3List[idJson].interpretation3Icon !== '' &&
                            <Tooltip title={extraitMP3[ids].TypeMp3List[idJson].interpretation3Nom}>
                              {displayIcon(extraitMP3[ids].TypeMp3List[idJson].interpretation3Icon)}
                            </Tooltip>
                          }

                          {extraitMP3[ids].TypeMp3List[idJson].langueIcon !== '' &&
                            <div className="gx-col gx-job-title  gx-d-sm-flex gx-text-truncate gx-px-8">
                              <Tooltip title={extraitMP3[ids].TypeMp3List[idJson].langueNom}>
                                <i className={`flag flag-24 gx-mr-2 ${extraitMP3[ids].TypeMp3List[idJson].langueIcon}`} />
                              </Tooltip>
                            </div>
                          }

                          <div className="gx-col gx-job-title  gx-d-sm-flex gx-text-truncate gx-px-8">
                            <Select
                              showSearch
                              style={{ width: '100%' }}
                              placeholder="Selection la choix de votre numéro de téléphone "
                              optionFilterProp="children"
                              onChange={handleChangeSelect}
                              defaultValue={selectOptions.get(extraitMP3[ids].TypeMp3List[idJson].visibilite)}
                              filterOption={(input, Option) => Option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                            >
                              {[...selectOptions].map(([value, label]) => <Option value={value}> {label} </Option>)}
                            </Select>
                          </div>

                          <div className="gx-col gx-job-title  gx-d-sm-flex gx-text-truncate gx-px-8">
                            <i className="icon icon-edit gx-fs-xl gx-text-gris" />
                          </div>

                          <div className="gx-col gx-job-title  gx-d-sm-flex gx-text-truncate gx-px-8">
                            <span className="gx-pointer">
                              <i className="icon icon-trash gx-pointer gx-text-danger gx-fs-xxl"
                                id={extraitMP3[ids].TypeMp3List[idJson].id}
                                onClick={e => this.showDeleteConfirmation(e.target.value, extraitMP3[ids].TypeMp3List[idJson].id, index, this)} />
                            </span>
                          </div>

                        </div>

                      </div>
                    )
                  })}
                  <NotificationContainer />

                  <Button type="primary" htmlType="submit" labelCol={{ xs: 24, sm: 5 }} wrapperCol={{ xs: 24, sm: 12 }}>
                    Enregistrer
                </Button>
                </Card>
              </li>
            </Card>
          )
        })}</div>
    )
  }
}

const VisibiliteFormMp3 = Form.create()(ListExtrait);

const mapStateToProps = ({ comedien }) => {
  const {
    extraitMP3,
    alertMessageUpdate,
    showMessageUpdate
  } = comedien;
  return {
    extraitMP3,
    alertMessageUpdate,
    showMessageUpdate
  }
};

export default connect(
  mapStateToProps,
  {
    userSignOut,
    getExtraitMp3,
    hideMessageUpdate,
    showUpdateLoader,
    updateMp3Visibilite
  })(VisibiliteFormMp3);

extraitMP3 is an object of objects that's why I used Object.keys(extraitMP3) I didn't know how to update the state correctly. extraitMP3 是一个对象的对象,这就是为什么我使用Object.keys(extraitMP3)我不知道如何正确更新状态。 this is the view :这是观点:

在此处输入图片说明

You should put your data in state and then change the state.您应该将数据置于状态,然后更改状态。 After changing the state the page automatically re-rendered and changed data of your state will be shown.更改状态后,页面会自动重新呈现并显示您状态的更改数据。 So in your delete function simply delete your chosen data and give your remaining data to your state.因此,在您的删除功能中,只需删除您选择的数据并将剩余的数据交给您的州。

Hope this helps, feel free to ask questions if I couldn't explain myself clearly.希望这会有所帮助,如果我无法清楚地解释自己,请随时提出问题。

I believe you can do this by calling something like and then just call this from within your delete我相信你可以通过调用类似的东西来做到这一点,然后从你的删除中调用它

refreshMp3(){ 
this.setState({getExtraitMp3: !this.state.getExtraitMp3});}

One of the ideas of React is to make the functionality you ask for simple to implement and it would update automatically. React 的想法之一是使您要求的功能易于实现并且会自动更新。 I'm going to abstract a bit from your example.我将从你的例子中抽象一下。 Think about your data in terms of what updates along with the UI.根据 UI 更新的内容来考虑您的数据。 This way we can simplify your component.这样我们就可以简化您的组件。 You have some items that you put in a table.您有一些物品放在桌子上。 Each item is a row and can be inside an array.每一项都是一行,可以在一个数组中。 We put that array in the state.我们将该数组放入状态。

class ListExtrait extends Component {
  constructor() {
    super();
    this.state = {
       rowsForTable: [...],
       somethingElse...
    }
    ...

Then in the JSX in the render method you can render the table rows using map :然后在渲染方法的 JSX 中,您可以使用map渲染表行:

rowsForTable.map(item => <div/li/whatever>{item.name or something else}</div>

This way whenever an item is gone from rowsForTable the component will automatically update it's view and the table rows will be up to date.这样,每当一个项目从rowsForTable消失时,组件就会自动更新它的视图,并且表格行将是最新的。

You can simply call the function while clicking the delete button say deleteHandler.您可以在单击删除按钮时简单地调用该函数,例如 deleteHandler。 On that function call the api you have made to delete the item and then after successfull delete again call the api that will show the item from database after certain time interval.在该函数中调用 api 来删除该项目,然后在成功删除后再次调用 api,该 api 将在一定时间间隔后从数据库中显示该项目。

Code: 

  import React, { Component } from 'react'

  export default class show_schedule extends Component {
    render() {
      state={

      }
      show_item_after_delete=()=>{
        setTimeout(()=>{
          axios.get(`http://127.0.0.1:8000/account/api/show_item/`).then(res=>{
          console.log('delete schedule data ',res.data)

        })
        },500)
      }
      deleteHandler=()=>{
        axios.delete(`http://127.0.0.1:8000/account/api/delete_item/${id}`).then(res=>{
          console.log(res.data)
        })
        this.show_item_after_delete()
      }
      return (
        <div>
          <button onClick={this.deleteHandler}>Delete</button>
        </div>
      )
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM