admin管理员组

文章数量:1384868

I have an app which shows a list of items in rows. Every item has a corresponding delete button. When I click it, it shows a modal with confirmation. When I click 'cancel', the action is canceled. When I click 'confirm' the modal do as follows:
1. It displays a loading icon
2. It changes the style (color and text - now it says it is done)
3. It removes the item

What I get so far is just displaying modal, same as in this article:
/
Plus just console logging when confirm is clicked.
How do I implement the feature?
Do I need to use Redux? Or is there some kind of library for confirmation dialogs?

My code:

I have an app which shows a list of items in rows. Every item has a corresponding delete button. When I click it, it shows a modal with confirmation. When I click 'cancel', the action is canceled. When I click 'confirm' the modal do as follows:
1. It displays a loading icon
2. It changes the style (color and text - now it says it is done)
3. It removes the item

What I get so far is just displaying modal, same as in this article:
https://daveceddia./open-modal-in-react/
Plus just console logging when confirm is clicked.
How do I implement the feature?
Do I need to use Redux? Or is there some kind of library for confirmation dialogs?

My code: https://codesandbox.io/s/6n03myqw8w

Share Improve this question edited Oct 19, 2017 at 20:24 n3stle asked Oct 19, 2017 at 20:01 n3stlen3stle 111 gold badge1 silver badge3 bronze badges 5
  • 1 No you don't need redux for this, you can have a function that runs when you hit okay on Modal confirmation that will delete the record. – Deano Commented Oct 19, 2017 at 20:05
  • I was thinking something like this: approveModal = () => { console.log('deleting'); // load icon, then change modal style, then delete item }; But how to implement that? – n3stle Commented Oct 19, 2017 at 20:11
  • @n3stle can you post your code? – Chase DeAnda Commented Oct 19, 2017 at 20:13
  • @n3stle post your code, preferably on codesandbox.io/s/new – Deano Commented Oct 19, 2017 at 20:14
  • already in the post, will do the same in codesandbox – n3stle Commented Oct 19, 2017 at 20:18
Add a ment  | 

2 Answers 2

Reset to default 2

Here's an example without using Redux. It shows how to use ponents to get around the issue of having to rely on a data store. The main container holds the data and actions and we simply pass these actions and the necessary data to remove and display a modal.

Now this doesn't account for the loading and style changes but you can bind these to the actions within the MockModal class to add a fake loading icon (since we're using data from a container, the data is instant). The style change could be added to the removeTask method in MockModal, or you can look into an animation technique to enhance the UI. The below is purely a functional implementation.

Let me know if you need more help.

class MockModal extends React.Component {
  removeTask = () => this.props.removeTask(this.props.data);
  closeModal = () => this.props.closeModal();
  render() {
    const { id, name } = this.props.data;
    if (this.props.displayModal) {
      return (
        <div>
          <h5>You want to delete task {id} : {name}</h5>
          <button onClick={this.removeTask}>Confirm</button>
          <button onClick={this.closeModal}>Close</button>
        </div>
      )
    }
    return null;
  }
}

class Task extends React.Component {
  showModal = (task) => this.props.show(this.props.task);
  render() {
    const { id, name } = this.props.task;
    return (
      <div>
        <h5>{id}:{name}</h5>
        <button onClick={this.showModal}>(REMOVE)</button>
      </div>
    )
  }
}

class App extends React.Component {
  state = {
    showModal: false,
    modal: {
      id: null,
      name: null,
    },
    tasks: [
      { id: 1, name: 'Star Wars' },
      { id: 2, name: 'Harry Potter' },
      { id: 3, name: 'Lord of the Rings' },
    ],
  }
  showModal = (task) => this.setState({ modal: task, showModal: true, });
  hideModal = () => this.setState({ showModal: false, });
  removeTask = (activeTask) => {
    const index = this.state.tasks.findIndex(task => {
      return task.id === activeTask.id;
    });
    this.setState({
      showModal: false,
      tasks: [
        ...this.state.tasks.slice(0, index),
        ...this.state.tasks.slice(index + 1),
      ]
    })
  }
  render(){
    return (
      <div>
        <MockModal 
          displayModal={this.state.showModal}
          closeModal={this.hideModal}          
          removeTask={this.removeTask}
          data={this.state.modal} 
        />
        {this.state.tasks.map(task => {
          return (
            <Task key={task.id} task={task} show={this.showModal} />
          )
        })}
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Do I need to use Redux?

No, definitely not

How do I implement the feature? [...] Or is there some kind of library for confirmation dialogs?

Sounds like you're already there. Instead of console.log() on confirm, do the thing! By "the thing" I'm referring to something along the lines of this...

handleConfirm = () => {
  this.setState({loading: true}); // show loading icon
  deleteItem(id)
    .then(() => {
      this.setState({
        loading: false, // hide loading icon
        success: true, // show colored success text
      });
    }
    .catch((err) => {
      // handle delete error here
    }

}

Your render function would then look something like this...

render() {
  const { loading, success } = this.state;
  return (
    {loading && <Loading />}
    {success && <SuccessMessage />}
    {!loading && !success && <ConfirmMessageWithButtons />}
  )
}

UPDATE: I see that you've provided code on code sandbox now, so here's a kludgy solution using your code. It's kludgy because it's simulating async operations using setTimeouts

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Modal from './ponents/Modal';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = { 
      isOpen: false,
      loading: false,
      success: false, 
    };
  }

  toggleModal = () => {
    this.setState({
      isOpen: !this.state.isOpen,
    });
  };

  approveModal = () => {
    this.setState({loading: true });
    setTimeout(() => this.setState({ 
      loading: false,
      success: true 
    }), 1000)
    setTimeout(() => this.setState({ 
      isOpen: false 
    }), 3000)
  };

  render() {
    const { loading, success } = this.state;
    return (
      <div className="App">
        {!success && !loading && <p>Item to delete</p>}
        <button onClick={this.toggleModal}>Delete</button>

        <Modal show={this.state.isOpen} onApprove={this.approveModal} onClose={this.toggleModal}>
          {loading && "Loading..."}
          {success && "Success (make me green)"}
          {!success && !loading && "Here's some text for the modal"}
        </Modal>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));

Here's a link https://codesandbox.io/s/10o12zzk63

本文标签: javascriptReact modal with delete functionalityStack Overflow