2015-10-06 16 views
10

Tôi có một thành phần tại một tuyến đường nhất định, nói app.com/cars/1Làm thế nào để unmount một thành phần về biến đổi tuyến đường

Tôi có một sidebar với các liên kết đến chiếc xe khác nhau, ví dụ như /cars/2, /cars/3, vv

Vấn đề tôi m có khi bạn thay đổi liên kết, giả sử đi từ cars/1 đến cars/2, thành phần không ngắt kết nối và tôi nhận được componentWillReceiveProps bị sa thải. Nếu tôi truy cập một trang khác có thành phần khác, hãy nói /trucks, thành phần chưa được gắn kết và tất cả đều tốt.

Tôi làm cách nào để ngắt kết nối thành phần của mình khi tuyến đường thay đổi? Tôi có tất cả các loại công cụ nhà nước và thông lượng mà tôi muốn xóa cho chiếc xe tiếp theo này. Hoặc nếu không tháo gắn kết, có cách nào điển hình để mọi người xử lý loại sự cố này không? Tôi không thể tưởng tượng điều này là không phổ biến.

(lưu ý tôi đang sử dụng phản ứng-router)

Trả lời

13

Tôi nghĩ theo cách thông thường để xử lý này chỉ là để hủy đăng ký và đăng ký lại người nghe của bạn, thiết lập lại trạng thái của bạn, và như vậy trong componentWillReceiveProps. Việc tạo trừu tượng xung quanh hành vi này là bình thường:

componentWillMount: function() { 
    this.setupStuff(this.props); 
} 

componentWillUnmount: function() { 
    this.tearDownStuff(); 
} 

componentWillReceiveProps: function(nextProps) { 
    this.tearDownStuff(); 
    this.setupStuff(nextProps); 
} 

setupStuff: function(props) { 
    this.setState(this.getDataFromStore(props.store)); 
    props.store.listen(this.handler); // or whatever 
} 

tearDownStuff: function(props) { 
    props.store.unlisten(this.handler); // or whatever 
} 

Tuy nhiên, nếu bạn thực sự muốn remount thành phần của mình, có một vài tùy chọn bạn có thể sử dụng.

Nếu bạn không muốn bất kỳ của các thành phần của bạn để vẫn gắn trên những thay đổi lộ trình, bạn có thể sử dụng the createElement option của router để thêm một chìa khóa duy nhất cho các thành phần:

function createElement(Component, props) { 
    var key = ...; // some key that changes across route changes 
    return <Component key={key} {...props} />; 
} 

// ... 

<Router createElement={createElement}> 
    ... 

Tuy nhiên, tôi don không đề nghị điều này. Nó không chỉ làm cho ứng dụng của bạn chậm hơn bởi vì mỗi thành phần tuyến đường được tính lại mỗi lần, nhưng nó cũng vô hiệu hóa hoàn toàn những thứ như hoạt ảnh giữa các trình hiển thị tiếp theo của cùng một trình xử lý tuyến đường với các đạo cụ khác nhau.

Nếu bạn chỉ muốn một nhất định lộ trình để luôn rerender, bạn có thể cung cấp cho nó một chìa khóa trong các phụ huynh qua React.cloneElement:

render: function() { 
    var key = ...; // some key that changes across route changes 
    return React.cloneElement(
    React.Children.only(this.props.children), 
    {key: key} 
); 
} 
1

tôi đã kết thúc chỉ thực hiện:

const createElement = (Component, props) => 
    <Component key={props.params.id} {...props}/>; 

ReactDOM.render(
    <Router history={browserHistory} createElement={createElement}> 
    <Route path="courses/:id" component={Page_courses_id}/> 
    </Router> 
); 

và bỏ qua các vấn đề hiệu suất tiềm năng (nếu chúng xảy ra), trong chi phí bảo trì tâm trí của tôi (của trạng thái đặt lại của tất cả các thành phần theo: phân đoạn động, dữ liệu tìm nạp lại trong componentWillReceiveProps, v.v.) không đáng giá.

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