setState()没有更新View - reactjs

时间:2015-05-14 18:59:55

标签: reactjs react-jsx

美好的一天伙计们,

我刚刚开始在项目中使用Reactjs,但我遇到了这个问题,可以提供一些帮助。我正在尝试实现一个订单管理系统,其中使用websockets将订单推送到浏览器,然后将reactjs视图更新为该数据。在交互期间在UI上处理的关联事件应该更新订单的状态。由于我刚开始使用Reactjs,我决定对我的数据集进行硬编码,以便我可以看到列表中显示的订单。但是,我无法点击列表并获取该被点击项目的详细信息以刷新视图并显示其分配的空间,当应用程序启动时,只显示订单列表,没有详细视图,如下面的代码所示或来自{ {3}}。所以问题是如何通过调用setState()来进行视图更新并显示正在进行的更新,或者问题是我在代码中我做错了什么?

/*This is a container for the title on the lefthand side - In Progress/Ready etc*/
var OrderItemsTitle = React.createClass({
    render: function(){
        return(
            <p className="row-progress">{this.props.title_text}</p>
        );
    }
});

OrderItemButtons = React.createClass({
    render: function(){
        return(
            <a href="javascript:void(0)" className="row-order " onClick={this.props.handleClick}>
                <img src={this.props.orderitem.image_url} />
                <span className="txt">{this.props.orderitem.cust_name}</span>
                <span className="status">{this.props.orderitem.time}</span>
            </a>
        );
    }
});

/*This is the component that loads the items on the leftside of the screen*/
var ListViewOrderItemsContainer = React.createClass({
    handleClick: function(orderitem){
        this.props.onUserInput(orderitem);
        console.log(this.props.selectedorderitem);
    },
    render: function(){
        var filteredNewOrderItem = this.props.orderitems.filter(function(orderitem){
            return orderitem.status.toLowerCase().search('new') !== -1;
        });
        var filteredReadyOrderItem = this.props.orderitems.filter(function(orderitem){
            return orderitem.status.toLowerCase().search('ready') !== -1;
        });
        var filteredInProgressOrderItem = this.props.orderitems.filter(function(orderitem){
            return orderitem.status.toLowerCase().search('in_progress') !== -1;
        });


        return(
            <div className='leftContainer'>
                <OrderItemsTitle title_text='New' />
                <div className='new_progress_container'>
                    {
                        filteredNewOrderItem.map(function(orderitem, i){
                            return <OrderItemButtons key={i} handleClick={this.handleClick.bind(this,
                                orderitem)} orderitem={orderitem} selectedorderitem={this.props.selectedorderitem} />
                        }, this)
                    }
                </div>    
                <OrderItemsTitle title_text='In Progress' />
                <div className='in_progress_container'>
                    {
                        filteredInProgressOrderItem.map(function(orderitem, i){
                            return <OrderItemButtons key={i} handleClick={this.handleClick.bind(this, 
                                orderitem)} orderitem={orderitem}/>
                        }, this)
                    }
                </div>
                <OrderItemsTitle title_text='Ready' />
                <div className='ready_container'>
                    {
                        filteredReadyOrderItem.map(function(orderitem, i){
                            return <OrderItemButtons key={i} handleClick={this.handleClick.bind(this, 
                                orderitem)} orderitem={orderitem}/>
                        }, this)
                    }
                </div>    
            </div> 
        );
    }
});

/*This is the productline details that is shown on the righthand side of the OMS*/
var ProductItemLineDetails = React.createClass({
    render: function(){
        return (
            <p>                
                <span className="pull-right">
                    <strong>{this.props.productItem.productItemPrice}</strong>
                </span>
                <span className="text-muted">
                    <strong>{this.props.productItem.productItemName}</strong>
                </span>
            </p>
        );
    }
});

/*This is the container element for ProductItemLineDetails above*/
var ProductItemDetails = React.createClass({
    render: function(){
        console.log("this.props.orderitem.length = ", this.props.orderitem.length);
        var productRow;
        if (this.props.orderitem.length === 0){
            productRow = "";            
        }
        else {
            productRow = this.props.orderitem.products.map(function(product, i){
                return <ProductItemLineDetails key={i} productItem={product} />             
            });
            console.log("productRow = ", productRow);
        }

        return ( 
            <div>
                <div className="media">
                    <small className="pull-right">
                        23h ago
                    </small>
                    <div className="media-body">
                        <h4 className="media-heading">
                            Bruno Otas
                        </h4>
                        <span className="text-muted">
                            (234)-8087616915
                        </span> 
                        <br />
                        <span className="text-muted">
                            2 days ago at 2:30 am - 11.06.2014
                        </span>
                    </div>
                </div> 
                    <hr />            
                    {productRow}
                    <hr />
            </div>
        );
    }
});

/**This is the main container that houses everything on the right hand side of the view**/
var DetailViewOrderItemsContainers = React.createClass({
    render: function() {        
        return (
            <div className="rightContainer">
                <ProductItemDetails orderitem={this.props.selectedorderitem} />
            </div>    
        );
    }
});

var ParentContainer = React.createClass({
    getInitialState: function(){
        return {
            selectedorderitem: []
        }
    },
    handleUserInput: function(orderitem){
        this.setState({
          selectedorderitem: orderitem
        });
        console.log("setstate hit",  this.state.selectedorderitem);
        console.log("setstate order", orderitem);
      },
    render: function(){
        return (
            <div className="parentContainer">
                <ListViewOrderItemsContainer orderitems={this.props.orderitems} 
                onUserInput={this.handleUserInput} 
                selectedorderitem={this.state.selectedorderitem} />
                <DetailViewOrderItemsContainers selectedorderitem={this.state.selectedorderitem} />
            </div>
        );
    }
});


//var inProgressOrderDetails = [
var orderitems = [
{id: "2942934-343323-234242234-23423",status: 'new', time: "2", image_url: "/assets/images/profile_small.jpg", cust_name: "Nnamdi Jibunoh", products:[{id: "2422-34333-34343", variants: [{productItemPrice:"1800", productItemName: "Ice Cream"}]}] },
{id: "2942934-343323-234242234-23424",status: 'new', time: "3", image_url: "/assets/images/profile_small.jpg", cust_name: "Adeolu Adamu", products:[{id: "2422-34333-34343", variants: [{productItemPrice:"1800", productItemName: "Ice Cream"}]}] },
{id: "2942934-343323-234242234-23425",status: 'in_progress', time: "4", image_url: "/assets/images/profile_small.jpg", cust_name: "Alaku Ishienyi", products:[{id: "2422-34333-34343", variants: [{productItemPrice:"1800", productItemName: "Ice Cream"}]}] },
{id: "2942934-343323-234242234-23426",status: 'ready', time: "5", image_url: "/assets/images/profile_small.jpg", cust_name: "Ogochukwu Maduabum", products:[{id: "2422-34333-34343", variants: [{productItemPrice:"1800", productItemName: "Ice Cream"}]}] },
{id: "2942934-343323-234242234-23427",status: 'ready', time: "6", image_url: "/assets/images/profile_small.jpg", cust_name: "Bruno Otas", products:[{id: "2422-34333-34343", variants: [{productItemPrice:"1800", productItemName: "Ice Cream"}]}] },
];

React.render(<ParentContainer orderitems = {orderitems} />, document.getElementById('react_body'));

2 个答案:

答案 0 :(得分:1)

setState方法运行良好...代码和数据存在问题。在这里你修复了你的小提琴。

https://jsfiddle.net/69z2wepo/8311/

ProductItemDetails中的渲染函数正在检查长度== 0的对象。虽然您在ParentContainer中将selectedorderitem定义为数组,但在更新状态时,您正在传递特定对象(并且您的产品详细信息需要一个数组)。另外,在您的ProductItemLineDetails中发生了类似的事情(数据集在价格和产品名称方面都是相同的,所以我稍微更改了一下,以便您可以看到它的工作原理。)

答案 1 :(得分:0)

也许是因为您在实际更新之前记录了状态:

handleUserInput: function(orderitem){
  this.setState({
    selectedorderitem: orderitem
  });
  console.log("setstate hit",  this.state.selectedorderitem);
  console.log("setstate order", orderitem);
}

应该是:

handleUserInput: function(orderitem){
  this.setState({
    selectedorderitem: orderitem
  }, function() {
    console.log("setstate hit",  this.state.selectedorderitem);
    console.log("setstate order", orderitem);
  })
}