2016-02-23 20 views
7

Tôi có một mảng các đối tượng được lưu trữ trong redux. Tôi muốn có thể lọc mảng đó dựa trên đầu vào của người dùng. Tôi có nên tạo một đối tượng trạng thái nhận mảng thông qua các đạo cụ và sửa đổi mảng đó, hay thực hành không tốt để trộn trạng thái và đạo cụ? Nếu có thể kết hợp cả hai, tôi có nên đặt trạng thái trong componentWillReceiveProps không?Cách tốt nhất để lọc bảng trong React

+2

todomvc là cách tiếp cận rất hợp lý để tuân theo trạng thái lọc. đây là những gì nó trông giống như với phản ứng/redux https://github.com/reactjs/redux/blob/master/examples/todomvc/components/MainSection.js – azium

+0

Tôi đang tìm kiếm thêm cho một cái gì đó như thế này https: // facebook. github.io/fixed-data-table/example-filter.html, ngoại trừ tôi nhận được mảng thông qua các đạo cụ thay vì dùng nó làm trạng thái của tôi. – Juliuszc

+2

Chính xác nguyên tắc tương tự cũng được áp dụng. Hãy nhớ rằng, đạo cụ của bạn là nhà nước của người khác. Bạn lưu trữ đầu vào người dùng của bạn như là một nơi nào đó .. hoặc redux hoặc trong thành phần bảng, sau đó lọc mảng đạo cụ của bạn chống lại trạng thái bộ lọc đó. – azium

Trả lời

11

Trạng thái xây dựng dựa trên đạo cụ có thể hơi phức tạp, có thể chấp nhận được nhưng bạn nên cân nhắc tất cả các tùy chọn của mình.

Cách đơn giản nhất để triển khai là lọc các đạo cụ theo phương pháp render của bạn. Nếu bạn có các thành phần đủ nhỏ mà không cập nhật cho quá nhiều lý do, và đặc biệt là nếu số phần tử trong danh sách là thấp, điều này có thể là phương pháp ưa thích:

class FilterList extends React.Component { 
    render() { 
    const { elements } = this.props; 
    const { filterStr } = this.state; 

    const filteredElements = elements 
     .filter(e => e.includes(filterStr)) 
     .map(e => <li>{ e }</li>) 

    return (
     <div> 
     <input 
      type="text" 
      value={ filterStr } 
      onChange={ e => this.setState({ filterStr: e.target.value }) } /> 
     <ul> 
      { filteredElements } 
     </ul> 
     </div> 
    ); 
    } 
} 

Lựa chọn tiếp theo là làm gì bạn đang mô tả và lấy được trạng thái được tính toán dựa trên trạng thái bộ lọc và các đạo cụ của thành phần được truyền cho nó. Điều này là tốt khi bạn có một thành phần phức tạp mà nhận được nhiều đạo cụ và được trả lại thường xuyên. Ở đây, bạn đang lưu vào bộ nhớ đệm các phần tử có thể xem và chỉ lọc danh sách khi cần lọc.

class FilterList extends React.Component { 
    constructor (props) { 
    this.state = { 
     viewableEls: props.elements 
    } 
    } 

    componentWillReceiveProps (nextProps) { 
    const { elements } = this.props; 
    const { filterStr } = this.state; 

    if (elements !== nextProps.elements) { 
     this.setState({ 
     viewableEls: this.getViewableEls(nextProps.elements, filterStr) 
     }) 
    } 
    } 

    getViewableEls (elements, filterStr) { 
    return elements.filter(el => el.includes(filterStr)) 
    } 

    handleFilterChange = e => { 
    const { elements } = this.props; 

    this.setState({ 
     filterStr: e.target.value, 
     viewableEls: this.getViewableEls(elements, filterStr) 
    }) 
    } 
    render() { 
    const { viewableEls } = this.state; 

    return (
     <div> 
     <input 
      type="text" 
      value={ filterStr } 
      onChange={ e => this.setState({ filterStr: e.target.value }) } /> 
     <ul> 
      { viewableEls.map(e => <li key={ e }>{ e }</li>) } 
     </ul> 
     </div> 
    ); 
    } 
} 

Và cuối cùng, Redux 'cách', mà đòi hỏi bạn phải vượt qua người sáng tạo và hành động filterStr như đạo cụ để các thành phần, có lẽ thông qua năm qua connect ở một nơi khác. Việc triển khai bên dưới đang sử dụng thành phần không có trạng thái vì chúng tôi không giữ lại trạng thái thành phần ở trạng thái thành phần là fitlerStr.

const FilterTable = ({ elements, filterStr, changeFilterStr }) => { 
    return (
    <div> 
     <input 
     type="text" 
     value={ filterStr } 
     onChange={ e => changeFilterStr(e.target.value) } /> 
     <ul> 
     { 
      elements 
      .filter(e => e.includes(filterStr)) 
      .map(e => <li key={ e }>{ e }</li>) 
     } 
     </ul> 
    </div> 
) 
} 
+0

Cảm ơn bạn đã dành thời gian trả lời câu hỏi theo chiều sâu! – Juliuszc

+0

Ví dụ đầu tiên và thứ ba khá tốt. Tuy nhiên tôi phải đưa ra vấn đề với ví dụ thứ hai. 'This.state.viewableEls' của bạn có nguồn gốc hoàn toàn từ các đạo cụ và trạng thái, trong khi các trường trạng thái thực sự chứa các phần thông tin duy nhất. Bạn tuyên bố điều này có một lợi ích bộ nhớ đệm, nhưng tôi không nhìn thấy nó; kể từ khi kết xuất chỉ được kích hoạt khi cập nhật đạo cụ/trạng thái. –

+0

Trong ví dụ contrived, bạn đúng, không có lợi ích cho 'caching', nhưng nếu bạn đang nhận được đạo cụ khác mà kích hoạt 'render', nhưng không ảnh hưởng đến giá trị của' this.state.viewableEls', sau đó có. Trừ khi tôi hiểu lầm bạn, tất nhiên. Cho phép nói rằng 90% số lần hiển thị lại được kích hoạt bởi thay đổi lệnh chống mà 'viewableEls' không phải là chức năng (cho phép nói rằng có một thành phần trò chuyện trong thời gian thực là một phần tử con) và' các phần tử' nằm trong phạm vi của hàng chục nghìn nguyên tố, sẽ có sự tái phân bổ không nhỏ nhưng không cần thiết mỗi khi có thông điệp mới. Không? –

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