2015-03-10 19 views
13

Gần đây chúng tôi đã chuyển sang React + Flux từ Angular để xây dựng một ứng dụng kinh doanh khá phức tạp.React + Flux: Bắt trạng thái ban đầu thành một cửa hàng

Lấy cách tiếp cận của việc có một thành phần container chuyển tất cả trạng thái vì thuộc tính xuống cây thành phần không phải là cách thiết thực để phát triển ứng dụng cho chúng tôi khi ứng dụng sử dụng các phương thức lớn như trang. Đủ trạng thái không được chuyển xuống các phương thức để họ tải dữ liệu của họ vào các cửa hàng của họ.

Vấn đề tôi có là tôi cần lấy một số trạng thái ban đầu (chuyển xuống dưới dạng đạo cụ) vào cửa hàng của thành phần phương thức. Trong this post những người tốt trên Facebook nói rằng nó ok để sử dụng đạo cụ cho trạng thái ban đầu khi đồng bộ hóa không phải là mục tiêu.

Đây là cách tôi nhận được tình trạng ban đầu vào cửa hàng của tôi hiện:

var ABC = React.createClass({ 
    ... 
    getInitialState: function() { 
    return ABCStore.getInitialABCState(this.props.initialA); 
    }, 
    ... 

var ABCStore = Reflux.createStore({ 
    ... 
    init: function() { 
    _state = { 
     a: null, 
     b: 'B init', 
     c: 'C init' 
    }; 
    }, 

    getInitialABCState: function(initialA) { 
    _state.a = initialA; 
    return _state; 
    }, 

    getABCState: function() { 
    return _state; 
    } 
    ... 

Tôi không chắc chắn những gì các thực hành tốt nhất là để làm điều này, hoặc cho dù đây là một anti-pattern Flux?

+1

Nó cảm thấy như bạn đang ở trên mép chống mẫu với cửa hàng đó. Tuy nhiên, điều tuyệt vời về Flux là đó là một khái niệm kiến ​​trúc hơn là một thành phần. Điều này có nghĩa là bạn có thể tạo các cửa hàng theo nhiều cách và giữ nó trong tinh thần Flux, trong một dự án tôi đã làm việc, chúng tôi chỉ sử dụng bộ điều phối từ thư viện Flux, có nghĩa là cửa hàng không được khởi tạo như ví dụ của bạn.Cửa hàng chỉ điền chính nó khi cần dữ liệu (hành động từ các thành phần hoặc bộ định tuyến). Tôi không nghĩ rằng ví dụ của bạn là thực hành xấu, nhưng nó mở ra một cuộc thảo luận tuyệt vời. – magnudae

+0

Vâng, tôi hy vọng sẽ khuấy động một số cuộc thảo luận, vì tôi cũng có cảm giác này, nhưng tôi cần nhiều thứ cụ thể hơn :) –

Trả lời

12

Tôi cảm thấy sai khi bạn đang sử dụng getInitialState() để thay đổi trạng thái cửa hàng của bạn. Bạn nên ít nhất là làm điều đó trong componentWillMount.

Tôi sẽ kích hoạt một hành động trong componentWillMount và để người quản lý cửa hàng cập nhật trạng thái nội bộ của cửa hàng (trường hợp này luôn luôn là trường hợp thông lượng). Sau đó xử lý sự thay đổi của thành phần của bạn cho các cửa hàng có thể tiêu thụ bất kỳ dữ liệu mà bạn đang gọi là "trạng thái ban đầu" của bạn

+0

Thêm vào câu trả lời của bạn Tôi đề nghị dành một vài giờ để nghiên cứu [ứng dụng chat của facebook] (https: // github .com/facebook/flux/blob/master/example/flux-chat/js /). Nó bao gồm gần như tất cả mọi thứ. –

+6

Có vẻ như ứng dụng trò chuyện đó nhận trạng thái ban đầu trong 'getInitialState', trái ngược với' componentWillMount' được đề xuất, mặc dù vậy. – Ryan

4

Reflux.listenTo thực hiện điều này khi bạn cung cấp một số thứ ba và Reflux.connect nhà máy mixin (có sử dụng Reflux.listenTo dưới mui xe) xử lý này cho bạn tự động. Dưới đây là ví dụ:

var Actions = Reflux.createActions({"doIt"}); 

var Store = Reflux.createStore({ 
    listenables: [Actions], 
    init: function() { 
     this.state = "I like to"; 
    }, 
    onDoIt: function() { 
     this.state = "Do it"; 
     this.trigger(this.state); 
    }, 
    getInitialState: function() { 
     return this.state; 
    } 
}); 

var DoItButton = React.createClass({ 
    mixins: [Reflux.connect(Store, "label")], 
    onClick: function() { 
     Actions.doIt(); 
    }, 
    render: function() { 
     return (<div onClick={this.onClick}>{this.state.label}</div>); 
    } 
}); 
+0

Cảm ơn câu trả lời - Tôi hơi bối rối. Trong ví dụ của bạn, bạn dường như không gửi trạng thái ban đầu đến cửa hàng, mà đúng hơn là bạn nhận được nó từ cửa hàng? Trong ví dụ của tôi, tôi cần lấy thuộc tính 'initialA' được cung cấp cho thành phần của tôi vào cửa hàng của tôi. Tui bỏ lỡ điều gì vậy? –

+0

@MarkusCoetzee vậy làm cách nào bạn đặt 'initialA' từ thành phần chứ không phải từ cửa hàng? – Spoike

+0

Thành phần nhận được thuộc tính này (được chuyển xuống từ vùng chứa chính). Thuộc tính này tạo thành một phần của trạng thái ban đầu của thành phần. Câu hỏi của tôi là về cách thức thông lượng của trạng thái ban đầu này vào cửa hàng –

0

Giống như các áp phích khác đã nói, điều tốt nhất cần làm là kích hoạt hành động trong componentWillMount. Trong ES6, điều này thường được thực hiện với một số constructor.

Dưới đây là một ví dụ về cách để làm điều này với ES6:..

(lưu ý rằng AuthorActions.initAuthors() phụ thuộc vào thực hiện, đây chỉ là một ví dụ này có thể nhận được trạng thái ban đầu từ cơ sở dữ liệu quan trọng nhất, mặc dù hành động này nên gửi tải trọng với trạng thái ban đầu cho điều phối viên)

var _authors = []; 
var AuthorStoreInstance; 

class AuthorStore extends EventEmitter { 

    constructor(props) { 
     super(props); 
    } 

    init() { 
     AuthorActions.initAuthors(); 
     this.emitChange(); 
    } 

    addChangeListener(cb) { 
     this.on(CHANGE_EVENT, cb); 
    } 

    removeChangeListener(cb) { 
     this.removeListener(CHANGE_EVENT, cb); 
    } 

    emitChange() { 
     this.emit(CHANGE_EVENT); 
    } 

    getAllAuthors() { 
     return _authors; 
    } 

    addAuthor(author) { 
     _authors.push(author); 
     this.emitChange(); 
    } 

    setAuthors(authors) { 
     _authors = authors; 
    } 

}; 


AuthorStoreInstance = new AuthorStore(); 

Dispatcher.register((action) => { 
    switch(action.actionType) { 
     case ActionTypes.CREATE_AUTHOR: 
      AuthorStoreInstance.addAuthor(action.author); 
      break; 
     case ActionTypes.INITIALIZE: 
      AuthorStoreInstance.setAuthors(action.initialData.authors); 
      break; 

     default: 
      //do nothing 
    } 
}); 

AuthorStoreInstance.init(); 

export default AuthorStoreInstance; 

Lưu ý cách hàm init không phải là một phần của hàm tạo. Điều này là do khi authorStore được xây dựng, gọi lại cho AuthorActions.initAuthors chưa được đăng ký với người điều phối.

Việc khởi chạy sẽ xảy ra sau khi cuộc gọi lại đã được đăng ký với người điều phối.

chỉnh sửa: Để làm rõ, initAuthors có thể trông giống như thế này:

initAuthors() { 
    var authors = AuthorAPI.getAllAuthors(); 

    Dispatcher.dispatch({ 
     actionType: ActionTypes.INITIALIZE, 
     initialData: { 
      authors: authors 
     } 
    }); 
} 
Các vấn đề liên quan