2015-03-20 13 views
8

Tôi đang tạo bản sao Word Dojo trong React/Flux. Các trò chơi chủ yếu là Boggle - bạn thực hiện lời bằng cách nhấp vào chữ cái liền kề trong một mạng lưới:Nested-loop React components với Flux, change-listeners trên cha mẹ hoặc con cái?

enter image description here

My Phản ứng linh kiện với nguồn của họ:

  1. Gameboard
  2. TileColumn
  3. Tile

Tất cả mã nguồn can be viewed here.


Làm thế nào nó hoạt động ngay bây giờ:

Có một GameStore chứa một mảng hai chiều của các đối tượng javascript. các đối tượng có giá trị chuỗi 'thư' và giá trị boolean 'hoạt động'. Khi người dùng nhấp vào một chữ cái, điều đó gửi đến GameStore, cập nhật mảng hai chiều và phát ra một sự kiện Thay đổi.

Thành phần GameBoard lắng nghe sự kiện thay đổi đó và sau đó hiển thị lại 10 TileColumn, lần lượt hiển thị 10 ô xếp kề. GameBoard có dữ liệu của cửa hàng như là một phần của trạng thái của nó và các ô có ký tự/trạng thái hoạt động của riêng chúng làm đạo cụ.

Vấn đề là việc thay đổi 1 chữ cái sẽ làm cho tất cả 100 ô được hiển thị lại.


shouldComponentUpdate

tôi đã cố gắng sử dụng shouldComponentUpdate trên Tile để xác định rằng nó chỉ nên cập nhật nếu giá trị 'hoạt động' của nó đã thay đổi, nhưng vấn đề là cả hai this.props.active và nextProps .active luôn có cùng giá trị: cả hai đều sai hoặc cả hai đều đúng.


trì hoãn trách nhiệm cho trẻ em

Ý tưởng khác tôi đã có được để có mỗi Ngói chịu trách nhiệm cập nhật riêng của mình, bằng cách đăng ký người nghe thay đổi trên gạch trực tiếp. Tôi nhận được một cảnh báo rằng tôi đã vượt quá số lượng người nghe, và có vẻ như 100 người nghe thay đổi tất cả bắn trên mỗi bản cập nhật thư sẽ kém hiệu quả hơn. Mặc dù đó là tất cả chỉ là Javascript, vì vậy chúng tôi muốn được tránh một số thao tác DOM ...


Performance

tôi bắn lên Profiler và ngay bây giờ, với phụ huynh làm tất cả các quản lý nhà nước , nó lấy 40ms để tái render toàn bộ hội đồng quản trị trên thư bấm. Đó không phải là xấu, nhưng khi trò chơi trở nên phức tạp hơn, tôi lo lắng nó sẽ trở thành một sự chậm trễ đáng chú ý.


Trợ giúp cần thiết

Cụ thể là tôi đang tìm lời khuyên về thực hành tốt nhất trong tình huống này (khi bạn đã lồng nhau, các thành phần lặp), và nếu shouldComponentUpdate giải pháp nhưng tôi chỉ sử dụng sai.

Cảm ơn!

Trả lời

12

Đúng, đây là ví dụ điển hình cho lý do tại sao Phản ứng không nhanh theo mặc định. Tôi có một ví dụ khá dài here cho chính xác loại vấn đề bạn đang cố giải quyết.

Về cơ bản bạn có hai vấn đề điển hình:

  1. Cách bạn initialize the tiles on the board là tốt, nhưng cách bạn modify the values for the tile chỉ đột biến đối tượng. Điều này làm cho nó khó để biết nếu một đối tượng nào đó đã thay đổi.

  2. Phản ứng ngây thơ lặp lại toàn bộ ứng dụng theo mặc định. Bạn chỉ có thể ngăn chặn việc tính toán lại các yếu tố tốn kém với render() nếu bạn sử dụng thông số shouldComponentUpdate một cách thông minh.

Giải pháp:

Sử dụng shouldComponentUpdate (hoặc chỉ cần sử dụng ReactComponentWithPureRenderMixin) để ngăn chặn tính toán lại lãng phí trong Tile. Tất nhiên, điều này sẽ không hoạt động trừ khi bạn làm một vài điều.

Solutions phúc:

  1. Bạn biết mà tính được phép biến đổi và thiết lập shouldComponentUpdate dựa trên những.

Chỉ được phép thay đổi tile.active? Bạn có thể chỉ cần define your callback để bạn chỉ kiểm tra tính bình đẳng của prevProps.tile.active === this.props.tile.active.

  1. Tạo đối tượng mới để so sánh nông của tham chiếu đối tượng thật dễ dàng.

Bạn có thể đã biết rằng var a = {}; var b = a sẽ làm cho nó để a === b, và rằng var c = {}; var d = {}; sẽ làm cho nó để c !== d. Thay thế đối tượng ngói hoàn toàn bất cứ khi nào bạn thực hiện cập nhật để bạn có thể sử dụng đối tượng ô mới có đối tượng cũ. Bằng cách này, hiệu suất nhanh chỉ theo nghĩa đen là mixins: [ReactComponentWithPureRenderMixin].

Điều này có thể tốn nhiều thời gian hơn bạn muốn, nhưng đó là cách tôi nhận được bất kỳ loại bộ sưu tập nào để hiển thị tốt trong React. Nếu không có những kỹ thuật này, tôi thực sự không thể nhận được my crappy etch-a-sketch component để hoạt động mà không cần phải dừng lại.

Chúc may mắn!

+0

Bạn cũng nên đặt dấu kiểm vào trong cột shouldComponentUpdate của TileColumn. Và ImmutableJS làm cho mọi thứ dễ dàng hơn cho PureRenderMixin để làm việc cùng.Chuyển sang ImmutableData, sử dụng mixin trong tất cả các thành phần của bạn, và bạn đã hoàn thành. – fisherwebdev

+0

Xin cảm ơn! Điều này cực kỳ hữu ích. Tôi khá chắc chắn lý do shouldComponentUpdate không hoạt động được vì các biến javascript-just-point-to-objects; bằng cách sử dụng Immutable.js nên khắc phục điều này và đó là một cái gì đó tôi đã có nghĩa là để làm anyway. –

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