2015-06-09 32 views
6

Here's a js fiddle hiển thị câu hỏi đang hoạt động.Làm thế nào để nối thêm vào dom trong React?

Trong hàm kết xuất của một thành phần, tôi hiển thị một div có lớp .blah. Trong componentDidMount chức năng của các thành phần tương tự, tôi đã mong đợi để có thể chọn lớp .blah và gắn với nó như thế này (kể từ khi thành phần đã gắn)

$('.blah').append("<h2>Appended to Blah</h2>"); 

Tuy nhiên, nội dung nối không hiển thị. Tôi cũng đã thử (cũng được hiển thị trong fiddle) để chắp thêm theo cách tương tự nhưng từ một thành phần cha vào một thành phần phụ, với cùng một kết quả, và cũng từ tiểu hợp phần vào không gian của thành phần cha với cùng một kết quả. Logic của tôi để cố gắng sau này là người ta có thể chắc chắn hơn rằng các yếu tố dom đã được trả lại.

Cùng lúc đó, tôi đã có thể (trong componentDidMount chức năng) để getDOMNode và thêm vào đó

var domnode = this.getDOMNode(); 
$(domnode).append("<h2>Yeah!</h2>") 

chưa lý do để làm với phong cách CSS Tôi muốn để có thể thêm vào sau một div với một lớp mà tôi biết. Ngoài ra, vì theo docsgetDOMNode bị phản đối, và nó không thể sử dụng thay thế cho getDOMNode để làm điều tương tự

var reactfindDomNode = React.findDOMNode(); 
$(reactfindDomNode).append("<h2>doesn't work :(</h2>"); 

Tôi không nghĩ getDOMNode hoặc findDOMNode là cách chính xác để làm những gì tôi m cố gắng làm.

Câu hỏi: Có thể nối thêm một id hoặc lớp cụ thể trong React không? Cách tiếp cận những gì tôi nên sử dụng để thực hiện những gì tôi đang cố gắng để làm (getDOMNode mặc dù nó bị phản đối?)

var Hello = React.createClass({ 
    componentDidMount: function(){ 

     $('.blah').append("<h2>Appended to Blah</h2>"); 
     $('.pokey').append("<h2>Can I append into sub component?</h2>"); 
     var domnode = this.getDOMNode(); 
     $(domnode).append("<h2>appended to domnode but it's actually deprecated so what do I use instead?</h2>") 

     var reactfindDomNode = React.findDOMNode(); 
     $(reactfindDomNode).append("<h2>can't append to reactfindDomNode</h2>"); 

    }, 
    render: function() { 
     return (
      <div class='blah'>Hi, why is the h2 not being appended here? 
      <SubComponent/> 
      </div> 
     ) 
    } 
}); 

var SubComponent = React.createClass({ 

     componentDidMount: function(){ 
     $('.blah').append("<h2>append to div in parent?</h2>"); 
     }, 

     render: function(){ 
     return(
       <div class='pokey'> Hi from Pokey, the h2 from Parent component is not appended here either?    
       </div> 
     ) 
     } 
}) 

React.render(<Hello name="World" />, document.getElementById('container')); 

Trả lời

4

Trong JSX, bạn phải sử dụng className, không phải class. Bảng điều khiển sẽ hiển thị cảnh báo về điều này.

cố định ví dụ: https://jsfiddle.net/69z2wepo/9974/

Bạn đang sử dụng React.findDOMNode không chính xác. Bạn phải chuyển thành phần React cho nó, ví dụ:

var node = React.findDOMNode(this); 

sẽ trả về nút DOM của chính thành phần đó.

Tuy nhiên, như đã đề cập, bạn thực sự nên tránh thay đổi DOM bên ngoài React. Toàn bộ vấn đề là mô tả giao diện người dùng một lần dựa trên trạng thái và đạo cụ của thành phần. Sau đó thay đổi trạng thái hoặc các đạo cụ để quay lại thành phần.

+0

nếu bạn nên tránh biến đổi dom, sau đó làm thế nào để mọi người sử dụng các thư viện như d3.js gắn thêm vào dom? nó có phù hợp không? – BrainLikeADullPencil

+0

Ah d3 ... vâng, có những ngoại lệ đối với nó, đặc biệt là khi nói đến thư viện của bên thứ ba. Nếu bạn tìm kiếm React + d3, bạn sẽ tìm thấy một vài cách tiếp cận cách xử lý này. –

+0

ngoại lệ? bạn có nghĩa là có những ngoại lệ cho quy tắc chung mà ta nên tránh đột biến dom? – BrainLikeADullPencil

2

Tránh sử dụng jQuery trong phản ứng, vì nó sẽ trở thành một chút của một antipattern. Tôi sử dụng nó một chút bản thân mình, nhưng chỉ cho tra cứu/đọc mà là quá phức tạp hoặc gần như không thể chỉ với các thành phần phản ứng.

Anyways, để giải quyết vấn đề của bạn, có thể chỉ cần tận dụng một đối tượng trạng thái:

<!DOCTYPE html> 
<html> 
    <head> 
    <title></title> 
    <script src="https://fb.me/react-0.13.3.js"></script> 

    </head> 
    <body> 
    <div id='container'></div> 
    <script> 
    'use strict'; 

var Hello = React.createClass({ 
    displayName: 'Hello', 

    componentDidMount: function componentDidMount() { 
     this.setState({ 
      blah: ['Append to blah'], 
      pokey: ['pokey from parent'] 
     }); 
    }, 

    getInitialState: function() { 
     return { 
     blah: [], 
     pokey: [] 
     }; 
    }, 

    appendBlah: function appendBlah(blah) { 
     var blahs = this.state.blah; 
     blahs.push(blah); 
     this.setState({ blah: blahs }); 
    }, 
    render: function render() { 
     var blahs = this.state.blah.map(function (b) { 
      return '<h2>' + b + '</h2>'; 
     }).join(''); 
     return React.createElement(
      'div', 
      { 'class': 'blah' }, 
      { blahs: blahs }, 
      React.createElement(SubComponent, { pokeys: this.state.pokey, parent: this }) 
     ); 
    } 
}); 

var SubComponent = React.createClass({ 
    displayName: 'SubComponent', 

    componentDidMount: function componentDidMount() { 
     this.props.parent.appendBlah('append to div in parent?'); 
    }, 

    render: function render() { 
     var pokeys = this.props.pokeys.map(function (p) { 
      return '<h2>' + p + '</h2>'; 
     }).join(''); 
     return React.createElement(
      'div', 
      { 'class': 'pokey' }, 
      { pokeys: pokeys } 
     ); 
    } 
}); 

React.render(React.createElement(Hello, { name: 'World' }), document.getElementById('container')); 
    </script> 
    </body> 
</html> 

Xin lỗi vì JSX chuyển đổi, nhưng chỉ là dễ dàng hơn cho tôi để kiểm tra mà không thành lập grunt :).

Dù sao, những gì tôi đang làm là tận dụng thuộc tính của tiểu bang. Khi bạn gọi setState, render() được gọi lại. Sau đó tôi tận dụng đạo cụ để truyền dữ liệu xuống thành phần phụ.

+0

nó không thực sự jquery tôi đang sử dụng nhưng một thư viện có một phương pháp phụ thêm. (Tôi cho rằng giải pháp của bạn vẫn sẽ được áp dụng). Tôi chỉ sử dụng jquery cho câu hỏi này vì nó minh họa vấn đề và dễ cài đặt trên jsfiddle .. Tôi sẽ thử câu trả lời của bạn và chấp nhận sau – BrainLikeADullPencil

1

Dưới đây là một phiên bản của JSFiddle của bạn với những thay đổi ít nhất tôi có thể thực hiện: tư vấn JSFiddle

agmcleod là đúng - tránh JQuery. Tôi sẽ thêm vào, tránh suy nghĩ của JQuery, điều này đã khiến tôi mất một thời gian để tìm ra. Trong React, phương thức render sẽ hiển thị những gì bạn muốn xem dựa trên trạng thái của thành phần. Đừng thao tác DOM sau khi thực tế, thao tác với nhà nước. Khi bạn thay đổi trạng thái, thành phần sẽ được hiển thị lại và bạn sẽ thấy thay đổi.

Đặt trạng thái ban đầu (chúng tôi chưa thêm bất kỳ thứ gì).

getInitialState: function() { 
    return { 
     appended: false 
    }; 
}, 

Thay đổi trạng thái (chúng tôi muốn nối thêm)

componentDidMount: function() { 
    this.setState({ 
     appended: true 
    }); 
    // ... 
} 

Bây giờ render chức năng có thể hiển thị các văn bản bổ sung hay không dựa trên tiểu bang:

render: function() { 
    if (this.state.appended) { 
     appendedH2 = <h2>Appended to Blah</h2>; 
    } else { 
     appendedH2 = ""; 
    } 
    return (
     <div class='blah'>Hi, why isn't the h2 being appended here? {appendedH2} 
     <SubComponent appended={true}/> </div> 
    ) 
} 
+0

nếu bạn nên tránh biến đổi dom, sau đó mọi người sử dụng thư viện như d3.js như thế nào mà phụ thêm vào dom? nó có phù hợp không? – BrainLikeADullPencil

+0

Tôi không biết. Tôi đã sử dụng d3.js nhưng không sử dụng React. Bạn _can_ thao tác DOM, bạn chỉ nên không làm điều đó như một phần của các thành phần React –

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