2015-03-12 22 views
5

Làm thế nào để bạn thay đổi vị trí của một thành phần mục trong phản ứng?React.js: Làm thế nào để bạn thay đổi vị trí của một thành phần mục

Trừ khi tôi đã hiểu sai, hãy phản hồi đơn đặt hàng các mục danh sách theo key, được biểu diễn trong DOM theo data-reactid, nhưng tôi không biết cách sửa đổi key thành phần trên trang.

tức là bạn lấy thành phần như thế nào, thay đổi nó là key và sau đó kích hoạt kết xuất để danh sách được sắp xếp lại hiển thị theo thứ tự bạn đã đặt?

ví dụ: trong ví dụ mã sau, khi liên kết Click me được nhấp vào, mục danh sách đầu tiên sẽ được hoán đổi với mục danh sách cuối cùng.

Lý tưởng nhất, chức năng này sẽ cho phép bạn tự động sắp xếp lại/di chuyển bất kỳ thành phần nào trên trang mà không thay đổi thứ tự các thành phần theo phương pháp render.

Dưới đây là một liên kết đến repo nơi đầy đủ các dự án tọa lạc: https://github.com/bengrunfeld/gae-react-flux-todos

var TodoBox = React.createClass({ 
    render: function(){ 
    return (
     <div className="todo-container"> 
     <h4>GAE React Flux Todos</h4> 
     <TodoList data={this.state.data} /> 
     </div> 
    ) 
    } 
}); 

var TodoList = React.createClass({ 
    changePosition: function(e){ 
    // Change position of list item (e.g. to top/certain position/end of list) 
    }, 
    render:function(){ 
    var todoNodes = this.props.data.map(function(todo) { 
     return (
     <Todo key={todo.id} id={todo.id}> 
      {todo.todoText} 
     </Todo> 
    ); 
    }); 
    return (
     <form className="todoList"> 
     {todoNodes} 
     <a onClick={this.changePosition}>Click me</a> 
     </form> 
    ) 
    } 
}); 

var Todo = React.createClass({ 
    render:function(){ 
    return (
     <div className="todoItem"> 
     <input type="text" className={this.props.id} onChange={this.checkInput} defaultValue={this.props.children} ref="todoItem"/> 
     </div> 
    ) 
    } 
}); 

Trả lời

7

Các key prop không được sử dụng để đặt yếu tố, nhưng để reconciliate nó giữa render cuộc gọi khác nhau. Các phần tử có cùng số key sẽ không được hiển thị lại mà thay vào đó khác với nhau để cập nhật DOM tối ưu. Xem Reconciliation

Nếu bạn muốn sắp xếp lại các yếu tố, bạn cần thay đổi vị trí của họ trong JSX của bạn hoặc trong mảng yếu tố bạn vượt qua như trẻ em trong phương pháp render của bạn (todoNodes).

Trong trường hợp của bạn, bạn có thể tạo một bản sao của this.props.data trong tình trạng phần TodoList, sau đó cập nhật bản sao đó trong phương pháp changePosition của bạn với một cái gì đó giống như this.setState({data: reorderedData}). Một nơi tốt để tạo bản sao đó sẽ ở trong getInitialState.

Phương pháp render của bạn TodoList sau đó sẽ được gọi là một lần nữa, và bạn sẽ lập bản đồ trên mới được bạn sắp xếp lại this.state.data để tạo ra một loạt các yếu tố Todo ra lệnh theo ý thích của bạn.

Tuy nhiên, hãy lưu ý rằng props in getInitialState is an anti-pattern. Vì dữ liệu của bạn sống ở trạng thái của thành phần TodoBox, một cách để tránh điều này là phải có TodoList gọi thành phần this.props.onReorder(reorderedData) trong phương thức changePosition của bạn. Thành phần TodoBox của bạn sau đó có thể chuyển trình xử lý sự kiện cho con của nó TodoList và cập nhật trạng thái của nó bằng dữ liệu mới bất cứ khi nào trình xử lý này được gọi.

var TodoBox = React.createClass({ 
    handleReorder: function(reorderedData) { 
    this.setState({data: reorderedData}); 
    }, 

    render: function(){ 
    return (
     <div className="todo-container"> 
     <h4>GAE React Flux Todos</h4> 
     <TodoList data={this.state.data} onReorder={this.handleReorder} /> 
     </div> 
    ) 
    } 
}); 

var TodoList = React.createClass({ 
    changePosition: function(e){ 
    // Change position of list item (e.g. to top/certain position/end of list) 
    // Create a copy of this.props.data and reorder it, then call 
    // this.props.onReorder to signal to the parent component that 
    // the data has been reordered 
    this.props.onReorder(reorderedData); 
    }, 

    render:function() { 
    var todoNodes = this.props.data.map(function(todo) { 
     return (
     <Todo key={todo.id} id={todo.id}> 
      {todo.todoText} 
     </Todo> 
    ); 
    }); 
    return (
     <form className="todoList"> 
     {todoNodes} 
     <a onClick={this.changePosition}>Click me</a> 
     </form> 
    ) 
    } 
}); 
+0

Cảm ơn bạn đã giải thích về cách React sử dụng khóa và ví dụ về cách giải quyết vấn đề. – Ben

+0

JsBin với sự kết hợp của mã từ câu hỏi và câu trả lời này, dữ liệu và phân loại được thêm vào: http://output.jsbin.com/yacacu –

0

Phím được sử dụng cho mục đích khác chứ không phải để sắp xếp. React sử dụng key s để tối ưu hóa các hoạt động Virtual DOM nội bộ của nó. Nó có nghĩa là bạn nói với React rằng "không quan trọng thứ tự của các anh chị em này, anh chị em cá nhân vẫn được xác định bởi khóa này". Đó là cách React biết liệu nó có nên thêm vào, chèn, xóa, hoặc nối thêm các anh chị em mới bằng cách sử dụng lại cái cũ, mà không ném đi những thứ không cần thiết.

Đối với câu hỏi sắp xếp của bạn: Để thay đổi thứ tự của anh chị em, chỉ cần sắp xếp mảng JavaScript this.props.data.

+0

mutation đạo cụ là thực hành xấu – tarikakyol

+0

Tôi thực sự không có nghĩa là nó như thế. (Tôi đã cố gắng để có được dữ liệu từ đạo cụ và sắp xếp nó.) Cảm ơn bạn đã chỉ ra điều này. – Rygu

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