组件未重新渲染 - ReactJS

时间:2016-02-15 01:01:22

标签: javascript reactjs

我有类似于笔记应用程序的东西,并且希望能够将卡片从一个组拖放到另一个组(通过使用react-dnd)。当然,在删除卡后,我想将其从源组中删除并将其添加到目标组。删除工作正常,但卡未在目标组中呈现。以下是相关代码:

App = React.createClass({
    getInitialState: function() {
        ...

        return {
            appState: appState
        }
    }


    removeCard: function(card) {
        var content = this.state.appState[card.groupId].content;
        content.splice(content.indexOf(card), 1);
        this.setState({ appState: this.state.appState });
    },

    addCard: function(card, target) {
        var content = this.state.appState[target.groupId].content;
        content.splice(content.indexOf(target) + 1, 0, card);
        this.setState({ appState: this.state.appState });
    },

    onCardDrop: function(source, target) {
        this.addCard(source, target); // didn't work
        this.removeCard(source); // worked
    },

    render: function() {
        var that = this;
        var appState = this.state.appState;

        return (
            <div>
                {_.map(appState, function(group) {
                    return (
                        <Group
                            key={group.id}
                            id={group.id}
                            group={group}
                            onCardDrop={that.onCardDrop} />
                    )
                })}
            </div>
        )
    }
});

因此,该卡将从源组中删除,但即使目标组的console.log显示该卡已存在,它也不会出现在目标组中。是否有可能由于某种原因组件没有重新渲染。

GroupCard组件分别呈现ulli

1 个答案:

答案 0 :(得分:2)

我花了一些时间根据您提供的代码制作一个工作示例......但它确实有效。您提供的代码没有问题。这表明问题出在代码的其他地方。

我无法给您完整的答案,因为您提供的代码段不符合Minimal, Complete, and Verifiable示例规则。虽然它很小,但它不完整,也不可验证。

我能做的就是粘贴我在这里制作的全部代码,并希望它对您有用。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src="https://npmcdn.com/react-dnd-html5-backend@2.1.2/dist/ReactDnDHTML5Backend.min.js"></script>
    <script src="https://npmcdn.com/react-dnd@2.1.0/dist/ReactDnD.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
    <style>
        ul {
            display: inline-block;
            padding: 10px;
            width: 100px;
            border: 1px solid gray;
            vertical-align: top;
        }
        li {
            display: block;
            padding: 0;
            width: 100px;
            text-align: center;
            box-sizing: border-box;
            position: relative;
        }
        li.group {
        }
        li.card {
            height: 100px;
            border: 1px solid black;
            line-height: 100px;
            margin-top: 5px;
            font-size: 25px;
            font-weight: bold;
            cursor: move;
        }
        li > span {
            vertical-align: middle;
            display: inline-block;
        }
    </style>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
    window.ItemTypes = {
        CARD: "card",
        GROUP_TITLE: "group-title"
    };
    </script>
    <script type="text/babel">
    var cardSource = {
      beginDrag: function (props) {
        return { cardId: props.id, groupId: props.groupId, card: props.card };
      }
    };
    function collect(connect, monitor) {
      return {
        connectDragSource: connect.dragSource(),
        isDragging: monitor.isDragging()
      }
    }
    var cardTarget = {
      drop: function (props, monitor) {
        var item = monitor.getItem();
        console.log(item.card)
        console.log(props.card)
        props.onCardDrop(item.card, props.card);
      },
      canDrop: function (props, monitor) {
        var item = monitor.getItem();
        return item.cardId != props.id;
      }
    };
    function collectTgt(connect, monitor) {
      return {
        connectDropTarget: connect.dropTarget(),
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop()
      };
    }
    window.Card = React.createClass({
        propTypes: {
            connectDragSource: React.PropTypes.func.isRequired,
            isDragging: React.PropTypes.bool.isRequired,
            isOver: React.PropTypes.bool.isRequired,
            canDrop: React.PropTypes.bool.isRequired
        },
        renderOverlay: function (color) {
            return (
              <div style={{
                position: 'absolute',
                top: 0,
                left: 0,
                height: '100%',
                width: '100%',
                zIndex: 1,
                opacity: 0.5,
                backgroundColor: color,
              }} />
            );
        },

        render: function() {
            var connectDragSource = this.props.connectDragSource;
            var isDragging = this.props.isDragging;
            var connectDropTarget = this.props.connectDropTarget;
            var isOver = this.props.isOver;
            var canDrop = this.props.canDrop;
            return connectDropTarget(connectDragSource(
                <li className="card" style={{opacity: isDragging ? 0.5 : 1}}
                ><span>{this.props.card.name}-{this.props.card.groupId}</span>
                {isOver && !canDrop && this.renderOverlay('red')}
                {!isOver && canDrop && this.renderOverlay('yellow')}
                {isOver && canDrop && this.renderOverlay('green')}
                </li>
            ));
        }
    });
    window.Card = ReactDnD.DragSource(ItemTypes.CARD, cardSource, collect)(window.Card);
    window.Card = ReactDnD.DropTarget(ItemTypes.CARD, cardTarget, collectTgt)(window.Card);
    </script>
    <script type="text/babel">
    window.Group = React.createClass({
        render: function() {
            console.log(this.props.group)
            var that = this;
            return (
                <ul>
                    <li className="group">Group #{this.props.group.id}</li>
                    {_.map(this.props.group.content, function(card) {
                        return (
                            <Card
                                key={card.name}
                                id={card.name}
                                groupId={card.groupId}
                                card={card}
                                onCardDrop={that.props.onCardDrop}
                                />
                        )
                    })}
                </ul>
            );
        }
    });
    </script>
    <script type="text/babel">
    window.App = React.createClass({
        getInitialState: function() {
            return {
                appState: [
                    {
                        id: 0,
                        content: [
                            {
                                groupId: 0,
                                name: "C1"
                            },
                            {
                                groupId: 0,
                                name: "C2"
                            },
                            {
                                groupId: 0,
                                name: "C3"
                            },
                            {
                                groupId: 0,
                                name: "C4"
                            }
                        ]
                    },
                    {
                        id: 1,
                        content: [
                            {
                                groupId: 1,
                                name: "C5"
                            },
                            {
                                groupId: 1,
                                name: "C6"
                            },
                            {
                                groupId: 1,
                                name: "C7"
                            },
                            {
                                groupId: 1,
                                name: "C8"
                            }
                        ]
                    }
                ]
            };
        },

        removeCard: function(card) {
            var content = this.state.appState[card.groupId].content;
            content.splice(content.indexOf(card), 1);
            this.setState({ appState: this.state.appState });
        },

        addCard: function(card, target) {
            var content = this.state.appState[target.groupId].content;
            content.splice(content.indexOf(target) + 1, 0, card);
            card.groupId = target.groupId;
            this.setState({ appState: this.state.appState });
        },

        onCardDrop: function(source, target) {
            this.removeCard(source); // worked
            this.addCard(source, target); // worked
        },

        render: function() {
            var that = this;
            var appState = this.state.appState;

            return (
                <div>
                    {_.map(appState, function(group) {
                        return (
                            <Group
                                key={group.id}
                                id={group.id}
                                group={group}
                                onCardDrop={that.onCardDrop}
                                />
                        )
                    })}
                </div>
            )
        }
    });
    window.App = ReactDnD.DragDropContext(ReactDnDHTML5Backend)(window.App);
    </script>
    <script type="text/babel">
      ReactDOM.render(
        <App />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>