codyc4321
codyc4321

Reputation: 9672

React app refreshing page for each item deletion

I have a React app here that works in many browsers:

<!DOCTYPE html>
<html>
  
<head>
  <title>React! React! React!</title>
  <script src="https://unpkg.com/[email protected]/dist/react.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  
  <style>
    body {
      padding: 50px;
      background-color: #66CCFF;
      font-family: sans-serif;
    }
    .todoListMain .header input {
      padding: 10px;
      font-size: 16px;
      border: 2px solid #FFF;
    }

    .todoListMain .header button {
      padding: 10px;
      font-size: 16px;
      margin: 10px;
      background-color: #0066FF;
      color: #FFF;
      border: 2px solid #0066FF;
    }

    .todoListMain .header button:hover {
      background-color: #003399;
      border: 2px solid #003399;
      cursor: pointer;
    }

    .todoListMain .theList {
        list-style: none;
        padding-left: 0;
        width: 255px;
    }

    .todoListMain .theList li {
        color: #333;
        background-color: rgba(255,255,255,.5);
        padding: 15px;
        margin-bottom: 15px;
        border-radius: 5px;
    }
  </style>
</head>
  
<body>
  
  <div id="container">
  
  </div>
  
  <script type="text/babel">
    var destination = document.querySelector("#container");

    // es6 is working in the browser :)
    let y = [1, 3, 6, 15, 39, 88].find(x => x > 39 && x < 90)

    var TodoItems = React.createClass({
        render: function(){
            var todoEntries = this.props.entries;

            function createTask(item){
                return (
                    <li key={item.key}>
                        <span>{item.text}</span>
                        <a  href="" data-id="{item.id}"
                            className="remove-filter"
                            onClick={this.props.remove.bind(item)}
                        >
                            remove
                        </a>
                    </li>
                )
            }

            // var listItems = todoEntries.map(createTask.bind(this));

            return (
                <ul className="theList">
                    {this.props.entries.map(createTask.bind(this))}
                </ul>
            );
        }
    });

    var TodoList = React.createClass({
        getInitialState: function(){
            return {
                items: []
            };
        },

        addItem: function(e) {
            var itemArray = this.state.items;
            itemArray.push(
                {
                    text: this._inputElement.value,
                    key: this.state.items.length
                }
            );
            this.setState({
                items: itemArray
            })
            this._inputElement.value = "";
            e.preventDefault();
        },

        // removing items from a list
        // https://stackoverflow.com/questions/27817241/how-to-remove-an-item-from-a-list-with-a-click-event-in-reactjs
        removeItem: function(item, event){
            event.preventDefault();

            var items = this.state.items.filter(function(itm){
                return item.id !== itm.id;
            });

            this.setState({ items: items });
        },

        render: function() {
            return (
                <div className="todoListMain">
                    <div className="header">
                        <form onSubmit={this.addItem}>
                            <input ref={(a) => this._inputElement = a}
                                placeholder="enter task" />
                            <button type="submit">add</button>
                        </form>
                    </div>
                    <TodoItems remove={this.removeItem} entries={this.state.items} />
                </div>
            );
        }
    });

    ReactDOM.render(
      <div>
        <TodoList/>
      </div>,
      destination
    );
  </script>
</body>
  
</html>

I have followed how to remove an item from a list with a click event in ReactJS? and it seems to be working, with a few issues.

First, the example references <a href data-..., but this did not work and redirected me to file:///Users/cchilders/tutorials/javascript/react/todo-list/true, where it got true from something it evaluated (true should be the index.html)

Deletion works using href="", but it flashes the page in an ugly manner, and the usual suspects to make an href do nothing don't work...

...if I try href="#" or href="javascript:;" and similar I get

embedded:60 Uncaught TypeError: Cannot read property 'preventDefault' of undefined

Second, I am getting warning

react.js:20478 Warning: bind(): React component methods may only be bound to the component instance. See TodoList

no matter what, for each thing I try.

Third, it is deleting all items in the list on remove, not just 1 item.

How can I make React do this deletion onclick without refreshing the page, and delete 1 item at a time?

Upvotes: 0

Views: 1197

Answers (1)

Mayank Shukla
Mayank Shukla

Reputation: 104359

There are few things that u need to change, check the jsfiddle for working example, do the changes in ur code accordingly.

*Don't write like this: {this.props.entries.map(createTask.bind(this))} instead of that just call a method {this.createTask()} from render, that function will return the complete list, n define createTask outside of the render method. like this:

createTask: function(){
  return this.props.entries.map(item=>{
    return (
      <li key={item.key}>
        <span>{item.text}</span>
        <a  href="#" data-id="{item.id}"
                className="remove-filter"
                onClick={()=>this.props.remove(item)}
        >
            remove
        </a>
      </li>
  )})
},

*U forgot to give the dead link to href, don't leave it empty define it like this: href="#".

*Don't bind the props remove method with onClick, use it like normal method calling, like this: onClick={()=>this.props.remove(item)}.

Check jsfiddle: https://jsfiddle.net/79eax14s/

Let me know if u need any help in this.

Upvotes: 2

Related Questions