2017-12-15 127 views
5

Tôi đang sử dụng ví dụ bên cung cấp trong tài liệu chính thức của phản ứng-router-v4 như một nguồn cảm hứng https://reacttraining.com/react-router/web/example/sidebarCách sử dụng các tuyến lồng nhau để thêm nội dung vào một trang mà không xóa nội dung của tuyến đường trước đó bằng phản ứng-router-v4?

1- Vì vậy, các URL ban đầu của ứng dụng của tôi sẽ là: localhost:3000/search-page/Lists

2- Tôi có một danh sách các liên kết có thể nhấp, khi nhấp hiển thị các dữ liệu nhấp vào thanh bên, và khi điều này xảy ra, URL được cập nhật: localhost:3000/search-page/Lists/itemList1selected

3 sau đó tôi nhấn vào nút "Hiển thị Danh sách số 2" để hiển thị một danh sách mới

4 - Mục tiêu của tôi là sử dụng các tuyến lồng nhau, khi tôi nhấp vào một Liên kết từ "Danh sách số 2". nó sẽ thêm nó bên dưới mục đã chọn từ "Danh sách số 1" ... và cập nhật URL cùng một lúc: localhost:3000/search-page/Lists/itemList1selected/itemList2selected

đây là mã hiện tại của tôi:

class MyComponent extends Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     showListButtonPressed: true 
    }; 
    this.showTheOtherList = this.ShowTheOtherList.bind(this); 
    } 

    showTheOtherList() { 
    this.setState({ 
    showListButtonPressed: !this.state.showListButtonPressed 
    }); 
    } 

render() { 
    const dataList1 = dataFromDataBase 
    .allItemsFromList1() 
    .map(list1 => ({ 
     path: `${this.props.match.params.type}/${list1.id}`, 
     mainList1:() => (
     <div> 
      {`${list1.company} ${list1.name} ${list1.price}`} 
     </div> 
     ), 
     sidebarList1:() => (
     <div> 
      <h3>item List 1 selected</h3> 
      {list1.company} 
     </div> 
     ) 
    })); 

    const dataList2 = fakeFlightApiDataTesting 
    .allItemsFromList2() 
    .map(list2 => ({ 
     path: `${this.props.match.params.type}/${list2.id}`, 
     mainList2:() => (
     <div> 
      {`${list2.company} ${list2.name} ${list2.price}`} 
     </div> 
     ), 
     sidebarList2:() => (
     <div> 
      <h3>item List 2 selected</h3> 
      {list2.company} 
     </div> 
     ) 
    })); 

    return (
     <div style={{ display: 'flex' }}> 
     <div style={{ width: '20%' }}> 

      {dataList1.map(route => (
      <div> 
       <Route 
       key={route.path} 
       path={`/search-page/${route.path}`} 
       exact={route.exact} 
       component={route.sidebarList1} 
       /> 
      </div> 
      ))} 

      {dataList2.map(route => (
      <div> 
       <Route 
       key={route.path} 
       path={`/search-page/${route.path}`} 
       exact={route.exact} 
       component={route.sidebarList2} 
       /> 
      </div> 
      ))} 
     </div> 
     <div> 
      // Switch the lists when button is pressed 
      {this.state.showListButtonPressed ? (
      <div> 
       <ul> 
       {dataList1.map(route => (
        <li key={route.path}> 
        <Link to={`/search-page/${route.path}`}> 
         {route.mainList1()} 
        </Link> 
        </li> 
       ))} 
       </ul> 
       <button onClick={this.showTheOtherList}> 
        Switch Lists 
       </button> 
      </div> 
      ) : (
      <div> 
       <ul> 
       {dataList2.map(route => (
        <li key={route.path}> 
        <Link to={`/search-page/${route.path}`}> 
         {route.mainList2()} 
        </Link> 
        </li> 
       ))} 
       </ul> 

       <button onClick={this.showTheOtherList}> 
       switch Lists 
       </button> 
      </div> 
      )} 
     </div> 
     </div> 
    ); 
    } 
} 

đây là một số ảnh chụp màn hình để có một ý tưởng tốt hơn:

What I already done and coded This is what I'm trying to achieve

Trả lời

5

Phần khó khăn là vì bạn đang sử dụng 2 tham số đường dẫn, nó không hoạt động chính xác giống như ví dụ mà chúng sử dụng. Giả sử bạn có tùy chọn "n" list1 và tùy chọn "m" list2. Điều đó có nghĩa là bạn sẽ n x m tổng số tuyến đường. Đối với nó để làm việc như thế này, bạn sẽ cần phải tạo một route list2 kết hợp với mọi tùy chọn list1. Sau đó, phím path cho danh sách2 sẽ trông giống như ${this.props.match.params.type}/${list1.id}/${list2.id}. Tôi nghĩ rằng điều này cũng có thể đạt được điều này bằng cách làm cho đường dẫn cho list2 ${this.props.match.url}/${list2.id}, nhưng nó sẽ yêu cầu list1 luôn luôn được chọn đầu tiên.

Đó là một trường hợp khá phức tạp, nhưng tôi hy vọng rằng sẽ giúp

3

Bạn có thể sử dụng phương pháp tiếp cận khác nhau để giải quyết việc này:

0.123.
  1. Lấy cảm hứng khác từ Bộ định tuyến React chính thức v4 recursive paths.

Sử dụng mẫu này, bạn có thể tạo danh sách lồng nhau sâu, sâu hơn 2 cấp.

  1. Kiểm tra xem đã có 1 mục được chọn ở cấp đầu tiên trong thanh bên của bạn và hiển thị <SidebarRoute /> cho trường hợp đó, vượt qua mục được chọn cấp thứ hai.

Tôi khuyên bạn nên (tùy chọn thứ 3) để giữ các mục được chọn trong trạng thái và hiển thị tương ứng trong thanh bên. Tùy chọn này sẽ hoạt động tốt, nếu bạn không có nghĩa vụ gửi liên kết bằng e-mail hoặc một thứ gì đó, chỉ muốn kết xuất. Sau đó, bạn có thể lưu trạng thái UI trong cửa hàng bạn chọn (redux, flux, bạn đặt tên cho nó).

dụ cơ bản cho cách tiếp cận thứ 2 (idlvl2 là những gì bạn đang cố gắng để hiển thị trong thanh bên): https://codesandbox.io/s/o53pq1wvz

+0

Tôi thực sự cố gắng để thích nghi với các quan chức Phản ứng Router v4 https://reacttraining.com/react-router/web/example/recursive-paths cho vấn đề của tôi. Bạn có bất kỳ ý tưởng làm thế nào để thực hiện điều đó? – AziCode

+0

Trước khi bạn định triển khai một cái gì đó, hãy giải thích những gì bạn đang cố gắng để đạt được UI-khôn ngoan. Câu hỏi của bạn được trả lời với các cách tiếp cận và ví dụ khác nhau. Tôi đoán bạn đang cố gắng để chỉ hiển thị 2 cấp độ, có thể đến sân bay khởi hành, nhưng mức này không nhất thiết có nghĩa là để được lồng nhau anyway. Chỉ cần đoán thôi. –

+0

Tôi nghĩ rằng tôi đã đưa ra rất nhiều chi tiết trong câu hỏi của mình, và tôi giải thích với mã và thậm chí cả hình ảnh giải thích mục tiêu của tôi là gì. Câu trả lời của Trey là câu trả lời cho tôi thấy đúng hướng và bạn chỉ có thể chọn một câu trả lời. Và bằng cách ví dụ mà bạn đăng là từ tài liệu chính thức, do đó, nó không cung cấp bất cứ điều gì mới – AziCode

1

này chỉ có thể là một lỗi đánh máy, nhưng trong làm cho thành phần của bạn, bạn đã quên thêm Router để div ngoài cùng của bạn . Các thành phần định tuyến phải được định nghĩa bên trong một thành phần Router.

+0

Tôi chưa quên thêm bộ định tuyến. Bộ định tuyến nằm trong thành phần chính (mà tôi không đăng trong câu hỏi). Trong các tuyến phản ứng-router-v4 được định nghĩa ở cấp thành phần. – AziCode

1

Theo ý kiến ​​của tôi, bạn có thể sử dụng thông số tìm kiếm.

Tuy nhiên, nếu bạn không có cơ hội thay đổi logic của thành phần bộ thu đường dẫn, bạn cần recursive paths Các tuyến đường như được đề xuất.

Vì vậy, về các thông số tìm kiếm. Vì vậy, thay vì thêm localhost:3000/search-page/Lists/itemList1selected/itemList2selected, hãy thêm localhost:3000/search-page/Lists?item1=itemList1selected&item2=itemList2selected.

Bạn có thể trích xuất các giá trị theo URLSearchParams, hãy cẩn thận nó không được hỗ trợ bởi IE.

Có 3 ưu điểm cho cách tiếp cận này. Đầu tiên, nó sẽ luôn hiển thị List, nó sẽ xử lý logic, không cần các Routing lồng nhau. Thứ hai, bạn có thể thêm nhiều mục, không chỉ hai mục. Url thứ ba sẽ xử lý tất cả logic, bạn có thể chia sẻ liên kết và mong đợi kết quả tương tự.

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