JSFiddle - React, Tailwind, and code Playground

HTML

<div class="wrapper">
        <form action="" class="add-animal">
            <input type="text" name="name" placeholder="Животное"> <button type="button">Добавить</button>
        </form><br>
        <div class="animals"></div>
    </div>



    <script type="template" id="animal-template">
        <%= name %> <button class="edit">edit</button> <button class="del">delete</button>
    </script>

    <script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
    <script src="//underscorejs.org/underscore-min.js"></script>
    <script src="//backbonejs.org/backbone-min.js"></script>

CSS

*
{
    padding: 0;
    margin: 0;
}

body
{
    font: 14px/1.4 'PT Sans';
    color: #333;
    background: #fff;
    margin: 50px;
}

.wrapper
{
    border: 1px solid #ccc;
    padding: 20px;
}

JavaScript

(function(){

    window.App = {
        Models:{},
        Collections:{},
        Views:{}
    };

    App.Models.Animal = Backbone.Model.extend({
        defaults:{
            name: ''
        },
        validate:function(attr){
            console.log('validate', typeof attr.name, attr);

            if(attr.name === '' || attr.name === null)
            {
                return 'min length 3 and max length 20';
            }
        }
    });

    App.Collections.Animal = Backbone.Collection.extend({
        model: App.Models.Animal,
        url:'animals.php'
    });

    App.Views.Animals = Backbone.View.extend({
        el:'.animals',
        tagName: 'ul',
        initialize:function(){
            this.collection.on('add',this.renderOne,this);
        },
        render:function(){
            _.each(this.collection.models,this.renderOne, this);
            return this;
        },
        renderOne:function(model){
            var AnimalView = new App.Views.Animal({ model:model });
            this.$el.append(AnimalView.render().el);
        }
    });

    App.Views.Animal = Backbone.View.extend({
        tagName: 'li',
        initialize:function(){
            this.model.on('destroy',this.remove,this);
            this.model.on('change',this.render,this);
            this.model.on('invalid',this.renderError,this);
        },
        render:function(){
            var tpl = _.template($('#animal-template').html(), this.model.toJSON());
            this.$el.html(tpl);
            return this;
        },
        events:{
            'click .edit':'edit',
            'click .del':'del'
        },
        del:function(){
            this.model.destroy();
        },
        edit:function(){
            var newName = prompt('Введите новое название', this.model.get('name'));
            if(newName === null)
            {
                return;
            }
            this.model.set({name:newName},{validate:true});
        },
        remove:function(){
     ...