2015-11-23 14 views
7

devs đồng nghiệp!Phản hồi: Trình nghe AppStore phải là một hàm

Tôi đã đào sâu vào Flux/React nhờ các hướng dẫn tại Egghead. Mặc dù tôi đã nghe nói rằng React đang chuyển động, tôi đã gặp một số thay đổi trong thư viện React trong khi làm theo các hướng dẫn đã nói.

Cho đến bây giờ tôi đã có thể khắc phục tất cả. Bây giờ, tôi đã chạy vào một bức tường gạch liên quan đến Cửa hàng. Theo hướng dẫn, tôi đang tạo một giỏ hàng, trong đó người dùng có thể thêm mọi thứ vào giỏ hàng của họ. Không phức tạp như vậy. Công việc bổ sung thực tế, nhưng việc hiển thị lại không được kích hoạt. Các mã sau đây cung cấp cho các lỗi gia tăng (đầy đủ mã sẽ được liệt kê dưới đây cũng):

addChangeListener: function(callback) { 
    this.on(CHANGE_EVENT, callback); 
}, 

mà kết quả trong lỗi chưa gặp: người nghe phải có một hàm. Tham số gọi lại là không xác định (vì vậy đó là nơi mà vấn đề nằm). Tuy nhiên, bởi vì tôi còn hơn cả cách làm việc mới của React, tôi đang gặp khó khăn trong việc tìm ra vấn đề. Đoạn sau đây là Cửa hàng từ hướng dẫn:

var AppStore = assign(EventEmitter.prototype, { 

    emitChange: function() { 
     this.emit(CHANGE_EVENT); 
    }, 
    addChangeListener: function(callback) { 
     this.on(CHANGE_EVENT, callback); 
    }, 
    removeChangeListener: function(callback) { 
     this.removeChangeListener(CHANGE_EVENT, callback); 
    }, 
    getCart: function() { 
     return _cartItems; 
    }, 
    getCatalog: function() { 
     return _catalog; 
    }, 
    getCartTotals: function() { 
     return _cartTotals(); 
    }, 
    dispatcherIndex: AppDispatcher.register(function (payload) { 
     var action = payload.action; 

     switch(action.actionType) { 
      case AppConstants.ADD_ITEM: 
       _addItem(payload.action.item); 
       break; 
      case AppConstants.REMOVE_ITEM: 
       _removeItem(payload.action.index); 
       break; 
      case AppConstants.INCREASE_ITEM: 
       _increaseItem(payload.action.index); 
       break; 
      case AppConstants.DECREASE_ITEM: 
       _decreaseItem(payload.action.index); 
       break; 
     } 

     AppStore.emitChange(); 

     return true; 
    }) 
}); 

Hãy lưu ý rằng đây là mã từ một hướng dẫn tại Egghead.io và tôi đang ở không có chiều chủ sở hữu (và nếu họ muốn tôi sẽ loại bỏ cho biết mã).

Nếu cần thêm mã hoặc giải thích, tôi sẽ sẵn lòng bắt buộc!

Cảm ơn mọi người :)

EDIT 1: Các thành phần đó là nghĩa vụ phải lắng nghe để thay đổi, nhưng không:

var Cart = React.createClass({ 

    getInitialState: function() { 
     return cartItems(); 
    }, 
    componentWillMount: function() { 
     debugger; 
     AppStore.addChangeListener(this.onChange); 
    }, 
    componentDidMount: function() { 
     debugger; 
     AppStore.addChangeListener(this.handleChange); 
    }, 
    handleChange: function() { 
     debugger; 
     this.forceUpdate(); 
    }, 
    _onChange: function() { 
     debugger; 
     this.setState(cartItems()); 
    }, 
    render: function() { 
     var total = 0; 
     var items = this.state.items.map(function (item, i) { 
      var subtotal = item.cost * item.qty; 
      total +=subtotal; 
      return (
       <tr key={i}> 
        <td><RemoveFromCart index={i} /></td> 
        <td>{item.title}</td> 
        <td>{item.qty}</td> 
        <td> 
         <Increase index={i} /> 
         <Decrease index={i} /> 
        </td> 
        <td>${subtotal}</td> 
       </tr> 
      ); 
     }); 

     return (
      <table className="table table-hover"> 
       <thead> 
        <tr> 
         <th></th> 
         <th>Item</th> 
         <th>Qty</th> 
         <th></th> 
         <th>Subtotal</th> 
        </tr> 
       </thead> 
       <tbody> 
        {items} 
       </tbody> 
       <tfoot> 
        <tr> 
         <td colSpan="4" className="text-right">Total</td> 
         <td>${total}</td> 
        </tr> 
       </tfoot> 
      </table> 
     ); 
    } 
}); 
+0

Bạn có thể cung cấp ví dụ nhỏ về hoạt động của sự cố không? Ngoài ra, bạn đã thử gỡ lỗi mã để xem * tại sao * gọi lại là null? Bạn đang gọi "addChangeListener" ở đâu? Tôi giả sử một thành phần? – christopher

+0

Tôi sẽ làm nếu có thể, nhưng chúng ta đang nói về một số tệp 20'ish và vấn đề thêm về bản quyền đối với mã thực tế (vì tôi không hoàn toàn chắc chắn nơi ranh giới sao chép/phân phối mã nói nằm). Về cơ bản, hàm '_addItem (payload.action.item)' được gọi là kích hoạt dòng 'Appstore.emitChange()'. Điều đó lần lượt, kích hoạt dòng 'emitChange: function()', kích hoạt dòng 'addChangeListener: function (callback)'. Đương nhiên, gọi lại là không xác định .. Nhưng tôi không biết đủ về React để đúng này:/ – Nickvda

+0

Tại sao/làm thế nào để 'emitChange' gọi' addChangeListener'? Nó không nên. Chức năng nào được gọi khi sự kiện được phát ra? Có vẻ như bạn đã không mã hóa chính xác mã của mình. Điều này không liên quan gì đến React btw. Chúng tôi thực sự không thể giúp bạn nếu chúng tôi không biết cách 'addChangeListener' được gọi. –

Trả lời

2

Đối với tôi, có vẻ như bạn đã làm việc ra hầu hết những điều này hoa văn nhưng bạn có chút bối rối. Có một bước cuối cùng mà bạn cần bao gồm, và đó thực sự là đăng ký các thành phần của bạn với các sự kiện mà cửa hàng đang đẩy ra.

this.emit(CHANGE_EVENT); 

Điều này sẽ đơn giản đẩy thứ gì đó ra ngoài. Nếu không ai nghe, thì không có gì sẽ thay đổi, vì vậy trong các thành phần của bạn, bạn cần phải thực sự lắng nghe sự kiện này.

Đối với một thành phần, có thể giống như thế:

React.createClass({ 
    componentDidMount: function() { 
     // Called after react has rendered the HTML in the DOM. 
     AppStore.addChangeListener(this.handleChange); 
    }, 

    render: function() { 
     return <div>{AppStore.someData}</div> 
    }, 

    handleChange: function() { 
     this.forceUpdate(); 
    } 
}); 

LƯU Ý: this.emit không nên gọi addChangeListener. Nó sẽ kích hoạt các cuộc gọi lại mà bạn có đã đăng ký bằng phương thức addChangeListener.

cải tiến tiềm năng

  • Một điều cần lưu ý là, mặc dù tất cả các dữ liệu của bạn đang trong AppStore, không phải tất cả các thành phần của bạn sẽ quan tâm đến tất cả các dữ liệu. Ví dụ: nếu bạn có thành phần Name, hiển thị tên người dùng, họ chỉ quan tâm đến NAME_CHANGE_EVENT. Họ không muốn tái xuất hiện mỗi lần một điều nhỏ nhặt xảy ra. Đây là xử lý không cần thiết bởi React, mặc dù React sẽ phỏng đoán không có gì thay đổi và sẽ không cập nhật DOM.
+0

Cảm ơn lời khuyên! Vẫn còn gỡ lỗi ở khắp mọi nơi để nắm bắt tốt hơn về bên trong của mẫu này :) Tôi đã thực hiện một sai lầm bằng cách nói 'this.emit' gây nên' addChangeListener', điều đó không đúng. Tuy nhiên, tôi đã đặt một trình nghe trong thành phần được cho là được cập nhật, nhưng không có hàm nào thực sự kích hoạt khi cập nhật xảy ra. Tôi sẽ đăng các thành phần trong OP. – Nickvda

+0

Và bạn đã định nghĩa '_addItem' ở đâu? – christopher

+0

Được rồi, sai lầm này là do sự ngu ngốc của chính tôi .. Tôi quên thêm một _ vào 'this.onChange', cái này phải là' this._onChange'. Ngay cả sau khi loại bỏ các chức năng bổ sung của bạn, nó vẫn hoạt động như một sự quyến rũ (mặc dù tôi đang gỡ lỗi địa ngục ra khỏi nó để tìm ra lý do tại sao *). Cảm ơn mặc dù tôi đang bỏ phiếu cho câu trả lời của bạn là giải pháp vì cải thiện tiềm năng của bạn là một cách hữu ích và nó đã đẩy tôi đi đúng hướng. Hàm _addItem() xảy ra trong một hàm riêng tư trong AppStore (mà là phạm vi toàn cục, trong quá trình biên dịch nó được bao bọc trong phạm vi riêng của nó). Cảm ơn bạn lần nữa! – Nickvda

Các vấn đề liên quan