map 函数在 reactjs 中不返回任何内容

IT技术 reactjs
2021-05-17 07:09:04

我的应用程序有 2 个组件。当我将props从父级传递给子级时,我使用 map 迭代props并在 todoItemListjs 组件中返回一个列表,但它给出了错误

必须返回有效的 React 元素(或 null)。您可能返回了 undefined、数组或其他一些无效对象。

这是我的组件

待办事项列表

    var React=require('react');
import TodoListItem from './TodoListItem.js';
    var TodoList = React.createClass({
        Remove: function(e){
           this.props.onDelete(e);
        },
        DragStart: function(e){
            this.dragged = e.currentTarget;
            e.dataTransfer.effectAllowed = 'move';
        },
        DragEnd: function(e){
            this.dragged.style.display="";
            var IshasNode = false

            Array.prototype.forEach.call (this.dragged.parentNode.childNodes, function (node) {
                if(node.className=="placeholder")
                                IshasNode = true;

            } );
            if(!IshasNode)
            return;
            this.dragged.parentNode.removeChild(placeholder);
            var data = this.props.items;
            var from = Number(this.dragged.dataset.id);
            var to = Number(this.over.dataset.id);
            if(from < to) to--;
            if(this.nodePlacement == "after") to++;
            data.splice(to, 0, data.splice(from, 1)[0]);
            this.setState({data: data});    
        },
        DragOver: function(e) {

            e.preventDefault();
            this.dragged.style.display = "none";

            if(e.target.className == "placeholder") return;
            this.over = e.target;

            var relY = e.clientY - this.over.offsetTop;
            var height = this.over.offsetHeight / 2;
            var parent = e.target.parentNode;

            if(relY > height) {
              this.nodePlacement = "after";
              parent.insertBefore(placeholder, e.target.nextElementSibling);
            }
            else if(relY < height) {
              this.nodePlacement = "before"
              parent.insertBefore(placeholder, e.target);
            }
        },
        render: function() {

            var createItem = function(itemText,i) {


                return (

                    <TodoListItem key={i} value={i} onDragEnd={this.DragEnd}
            onDragStart={this.DragStart} onRemove = {this.Remove} AllItems={itemText}>{itemText}</TodoListItem>


                );
            };
            var allitems = this.props.items;
            // Here is the filter function 
            var status = this.props.filter[0].Status;
            switch (status){
                case 'false':
                 allitems = allitems.filter(t => !t.isDone)
                 break;
                 case 'true':
                 allitems = allitems.filter(t => t.isDone)
            };
            // Here is the search function 
            var queryText = this.props.filter[0].keyword;

            if(queryText){
                var queryResult=[];
                allitems.forEach(function(item){
                    if(item.item.toLowerCase().indexOf(queryText)!=-1)
                    queryResult.push(item);
                });
                return <ul onDragOver={this.DragOver}>{queryResult.map(createItem,this)}</ul>;
            }

            return  <ul onDragOver={this.DragOver}>{allitems.map(createItem,this)}</ul> ;
        }
    });
export default TodoList;

待办事项列表项

    var React=require('react');


var TodoListItem = React.createClass({
getInitialState : function(){
            return {items:[{item:'',isDone:false,cost:0}]};
        },


    componentDidMount: function() {

  },

        ChangeHandler: function(e){
            this.setState({
              value: e.target.checked
            });
            this.props.children.isDone = e.target.checked;
        },
        RemoveHandler: function(){
           this.props.onRemove(this.props.value);
        },
        DragEndHandler : function(e){
                this.props.onDragEnd(e);
            },
        DragStartHandler : function(e){
                this.props.onDragStart(e);
        },
        render: function(){




            var _style = "line-through";
            var space="                                         ";
            if(!this.props.children.isDone)
            _style ="none";

    this.props.AllItems.items.map(function(todo)
        {

        console.log(todo.cost)
        return (

              <li data-id={this.props.value} 
                        key={this.props.value} draggable="true" onDragEnd={this.DragEndHandler}
                    onDragStart={this.DragStartHandler}><button type="button" className="close pull-right" aria-hidden="true" onClick={this.RemoveHandler}>&times;</button><input type="checkbox" onChange={this.ChangeHandler} defaultChecked={this.props.children.isDone} /><span style={{"textDecoration": _style}}>{todo.item}{todo.cost}</span></li>
            );
        },this)


        }
    });

export default TodoListItem;

我也尝试将代码包装在 div 标签中,但它不起作用

皮斯指南

2个回答

因为您没有从 TodoListItem 组件返回任何内容,所以请检查渲染方法。

要么将地图部分放在这样的 div 中:

return(
    <div>
        {
            this.props.AllItems.items.map(function(todo){
                ....
            }
        }
    </div>
)

或者将地图结果存储在一个变量中并返回最终结果,如下所示:

render(){
    let data = this.props.AllItems.items.map(function(todo){
        ....
    }

    return(
        <div> {data} </div>
    );
}

正如在@ivarni提出意见:该<li>元素应该去里面<ul>div是不允许在那里,根据我刚才提供的原因的错误,从而改变结构。

参考。

您在 TodoListItem 渲染函数中不返回任何内容。您的回报来自地图回调。将所有内容包装在一个 div 中并返回它。

return (<div>
   {this.props.AllItems.items.map(function(todo)
    {

    console.log(todo.cost)
    return (

          <li data-id={this.props.value} 
                    key={this.props.value} draggable="true" onDragEnd={this.DragEndHandler}
                onDragStart={this.DragStartHandler}><button type="button" className="close pull-right" aria-hidden="true" onClick={this.RemoveHandler}>&times;</button><input type="checkbox" onChange={this.ChangeHandler} defaultChecked={this.props.children.isDone} /><span style={{"textDecoration": _style}}>{todo.item}{todo.cost}</span></li>
        );
    },this);}
</div>)