2015-09-26 17 views
18

Tôi hơi bị suy nghĩ về cách thực hiện bộ giảm tốc nơi các thực thể của nó có thể có con cùng loại.Làm thế nào để xử lý các thực thể dạng cây trong bộ giảm tốc Redux?

Hãy lấy các nhận xét về màu đỏ làm ví dụ: mỗi nhận xét có thể nhận xét con của trẻ có thể tự nhận xét, v.v. Vì lý do đơn giản, nhận xét là bản ghi loại {id, pageId, value, children}, với pageId trang reddit.

Làm thế nào để mô hình hóa bộ giảm tốc xung quanh điều đó? Tôi đã suy nghĩ của việc có giảm là một bản đồ -> id của các ý kiến, nơi bạn có thể lọc theo trang bằng cách sử dụng pageId.

Vấn đề là ví dụ khi chúng tôi muốn thêm nhận xét vào lồng nhau: chúng tôi cần tạo bản ghi trên thư mục gốc của bản đồ và sau đó thêm id của nó vào thuộc tính cha mẹ.Để hiển thị tất cả nhận xét chúng ta cần lấy tất cả chúng, lọc những thứ mà chúng ta đứng đầu ở trên (sẽ được giữ trong bộ giảm tốc trang như một orderList chẳng hạn) và sau đó lặp lại chúng, lấy từ các đối tượng bình luận khi chúng ta gặp trẻ em bằng cách sử dụng đệ quy.

Có cách tiếp cận nào tốt hơn hay thiếu sót không?

+0

Tôi nghĩ bạn có thể thử normalizr: https://github.com/gaearon/normalizr Chưa tự mình sử dụng, vì vậy tôi không chắc liệu nó có giúp bạn trong trường hợp của bạn hay không. – Simon

+0

Tôi biết về normalizr, tôi tự hỏi nếu có một giải pháp "được chấp nhận" về cách xử lý nó trong các thành phần. Trừ khi bạn kết nối() mọi nhận xét bạn sẽ cần phải làm ngược lại với normalizr trên mỗi thay đổi và ngay cả khi bạn kết nối trông hơi giống một mớ hỗn độn –

Trả lời

32

Các giải pháp chính thức để này là sử dụng normalizr để giữ trạng thái của bạn như thế này:

{ 
    comments: { 
    1: { 
     id: 1, 
     children: [2, 3] 
    }, 
    2: { 
     id: 2, 
     children: [] 
    }, 
    3: { 
     id: 3, 
     children: [42] 
    }, 
    ... 
    } 
} 

Bạn nói đúng đó bạn cần phải connect() thành phần Comment vì vậy mỗi đệ quy có thể truy vấn các children nó quan tâm từ cửa hàng Redux:

class Comment extends Component { 
    static propTypes = { 
    comment: PropTypes.object.isRequired, 
    childComments: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired 
    }, 

    render() { 
    return (
     <div> 
     {this.props.comment.text} 
     {this.props.childComments.map(child => <Comment key={child.id} comment={child} />)} 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state, ownProps) { 
    return { 
    childComments: ownProps.comment.children.map(id => state.comments[id]) 
    }; 
} 

Comment = connect(mapStateToProps)(Comment); 
export default Comment; 

Chúng tôi nghĩ đây là một sự thỏa hiệp tốt. Bạn vượt qua comment làm giá đỡ, nhưng thành phần truy xuất childrenComments từ cửa hàng.

+0

Làm thế nào để bạn thực sự làm điều đó với Schemas? Vui lòng cho ví dụ – alexrogins

+0

Ví dụ này sử dụng normalizr: https://github.com/reactjs/redux/tree/master/examples/real-world. Normalizr cũng có các bài kiểm tra hy vọng sẽ cho thấy cách sử dụng nó. –

+0

Điều gì sẽ xảy ra nếu dữ liệu của bạn không đến từ API? Tôi có nên mô hình hóa dữ liệu của mình như normalizr không? – Dave

1

Cấu trúc cửa hàng (giảm tốc) của bạn có thể khác với mô hình xem mong muốn của bạn (một trong những bạn chuyển làm đạo cụ cho các thành phần). Bạn có thể giữ tất cả các chú thích trong mảng và ánh xạ chúng thành một cây bằng các liên kết trong mapStateToProps trên thành phần 'thông minh' mức cao. Bạn sẽ nhận được quản lý trạng thái đơn giản trong bộ giảm tốc và một mô hình xem tiện dụng cho các thành phần để làm việc.

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