2015-01-07 45 views
10

Tôi có một thành phần chung để ánh xạ các thành phần con của nó để chỉ lọc các trẻ em thuộc một loại nhất định, như được tìm thấy bên dưới.So sánh hai thành phần - là thành phần X một thể hiện của thành phần A

Tuy nhiên, việc sử dụng thuộc tính type chỉ là phỏng đoán và tôi không thể tìm thấy tài liệu đó. Không chỉ vậy, việc ghi lại nó cho thấy nó là một hàm - mà không thể thực hiện được. Trên hết, có một số vấn đề cần được giải quyết khi sử dụng Browserify.

Một tùy chọn khác là đọc child.prototype.displayName. Nhưng điều đó cũng cảm thấy sai.

Câu hỏi: Về cơ bản, tôi đang tìm một cách chắc chắn để so sánh xem hai thành phần ReactJS có bình đẳng không.

VÍ DỤ

(Cập nhật: không phải là xấu sau khi tất cả)

var Foo = React.createClass({ 
    render: function() { 
     return <div>Foo</div>; 
    } 
}); 

var Bar = React.createClass({ 
    render: function() { 
     return <div>Bar</div>; 
    } 
}); 

var Main = React.createClass({ 
    render: function() { 
     var filteredChildren = []; 

     filteredChildren = React.Children.map(function(child) { 
      if (child.type === Foo.type) { 
       return child; 
      } 
     }); 

     return (
      <div> 
       {filteredChildren} 
      </div> 
     ); 
    } 
}); 

React.render(<Main><Foo /><Bar /></Main>, document.body); 
+0

Trong những cảm giác làm bạn muốn biết các thành phần đều bình đẳng? Có nghĩa là họ làm cho cùng một đầu ra? –

+1

Không, chúng có thể (và) hoàn toàn khác nhau. Tôi cần phải biết nếu họ là một thể hiện của React.createClass(). – David

+1

Liên quan: https://www.bountysource.com/issues/3127455-proptypes-define-children-component-type – David

Trả lời

12

Tôi nghĩ rằng ví dụ của bạn là đúng.

Thật vậy, trong React 0.12 child.type === Foo.type là so sánh duy nhất hoạt động.
Điều này liên quan đến React 0.12 đang trong quá trình deprecating wrapper functions.

Khi 0.13 hết, child.type chính nó sẽ là Foo.

Nitpick: không sử dụng this.props.children.map, this won't work when there is less than two children.
Sử dụng React.Children.map để thay thế.

+0

Cảm ơn bạn đã tiết lộ một số ánh sáng! Điều này giải thích tại sao 'child.type' dường như là một hàm. Đối với việc nitpicking, bạn hoàn toàn đúng, và thực sự người ta nên sử dụng React.Children.map! – David

+2

Mặc dù không liên quan cụ thể đến ví dụ câu hỏi này, nếu bạn tạo các lớp ES6 thay vì sử dụng React.createClass, bạn có thể sử dụng cá thể của: 'child.type.prototype instanceof Foo' - Tôi phát hiện ra rằng trong [câu hỏi tương tự của riêng tôi] (http://stackoverflow.com/questions/35584279/looping-this-props-children-how-do-i-test-their-type?stw=2) – mjohnsonengr

2

Loại api bạn đang tạo ra là yếu và khó hiểu. Bạn không nên coi các phần tử là dữ liệu. Nếu bạn cần lọc, chuyển dữ liệu đến thành phần.

<Main things={[ 
    {type: 'Foo', element: <Foo />}, 
    {type: 'Bar', element: <Bar />}, 
    {type: 'Bar', element: <div>I'm lying but it doesn't matter</div>}, 
]} /> 
var Main = React.createClass({ 
    render: function(){ 
     var filteredChildren = this.props.things.map(function(thing){ 
      return thing.type === 'Foo' ? thing.element : false; 
     }); 

     return <div>{filteredChildren}</div>; 
    } 
}); 
+1

Hầu hết thời gian này là sự thật. Có những trường hợp hiếm hoi khi so sánh là hợp pháp. Ví dụ: nếu thành phần của bạn cũng xuất các thành phần phụ và muốn áp dụng điều trị đặc biệt cho các loại cụ thể, ví dụ: '

một số'. –

+1

Và tại sao bạn cần phải biết cái nào trong trường hợp như thế? Menu.Item sẽ hiển thị một mục menu và Menu.Separator sẽ hiển thị một dấu phân cách. Và Menu sẽ chỉ hiển thị nội dung của nó và (điều kiện) bao gồm this.props.children. – FakeRainBrigand

+0

Tôi đã có một trường hợp sử dụng, nơi tôi muốn bọc mỗi 'trẻ em được thông qua trong một' div', ngoại trừ dấu phân cách. Mặc dù bạn đúng, với 'Menu.Item' Tôi sẽ không thực sự cần kiểm tra này - tôi đã quá lười biếng để bọc từng món đồ. –

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