2017-12-15 185 views
5

używam przykład paska bocznego przewidzianej w oficjalnej dokumentacji reagować-Router-V4 jako inspiracja https://reacttraining.com/react-router/web/example/sidebarJak korzystać z tras zagnieżdżonych w celu dodania treści do strony bez usuwania zawartości poprzedniej trasy z react-router-v4?

1- więc początkowy adres URL mojej aplikacji będzie: localhost:3000/search-page/Lists

2- mam lista klikalne linki które po kliknięciu wyświetlacz klikniętego dane na pasku bocznym, a gdy to nastąpi URL zostanie zaktualizowany: localhost:3000/search-page/Lists/itemList1selected

3- i następnie nacisnąć na przycisk „Pokaż listę numer 2”, aby wyświetlić nową listę

4 - moim celem jest użycie tras zagnieżdżonych, gdy kliknę link z "Listy numer 2". byłoby dołączyć go pod wybranym z „numerem 1” Lista pozycji ... i zaktualizować adres URL w tym samym czasie: localhost:3000/search-page/Lists/itemList1selected/itemList2selected

Oto mój bieżący kod:

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> 
    ); 
    } 
} 

oto kilka screenów mieć lepszy pomysł:

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

Odpowiedz

5

Trudne jest to, że ponieważ używasz 2 ścieżek, nie działają one dokładnie tak samo, jak ich przykład. Załóżmy, że masz opcje "n" list1 oraz opcje "m" list2. Oznacza to, że chcesz n x m łącznych tras. Aby działało w ten sposób, trzeba utworzyć trasę list2 połączoną z każdą opcją listy1. Wtedy klucz path dla listy2 będzie wyglądał jak ${this.props.match.params.type}/${list1.id}/${list2.id}. Myślę, że można to również osiągnąć, tworząc ścieżkę dla list2 ${this.props.match.url}/${list2.id}, ale wymagałoby to, aby lista1 była zawsze wybierana jako pierwsza.

Jest to dość skomplikowany przypadek, ale mam nadzieję, że pomaga

3

można stosować różne podejścia do rozwiązania tego problemu:

  1. Uzyskaj kolejną inspirację z oficjalnego routera React v4 recursive paths.

Za pomocą tego wzoru można tworzyć listy głęboko zagnieżdżone, o głębokości większej niż 2 poziomy.

  1. Sprawdź, czy na pasku bocznym jest już zaznaczony 1 element na pierwszym poziomie i wyrenderuj dla tego przypadku kolejny <SidebarRoute />, przekazując drugi element jako rekwizyt.

Proponuję (trzecią opcję), aby przytrzymać wybrane elementy w stanie i odpowiednio wyświetlić na pasku bocznym. Ta opcja zadziała dobrze, jeśli nie jesteś zobowiązany do wysyłania linków przez e-mail lub coś takiego, po prostu chcesz renderować. Następnie możesz zapisać stan interfejsu w wybranym sklepie (redux, flux, nazwij to).

Podstawowe przykładem 2 podejścia (idlvl2 to, co staramy się pokazać w pasku bocznym): https://codesandbox.io/s/o53pq1wvz

+0

Jestem rzeczywiście próbuje przystosować oficjalna React Router v4 https://reacttraining.com/react-router/web/example/recursive-paths do mojego problemu. Czy masz pojęcie, jak to wdrożyć? – AziCode

+0

Zanim zaczniesz coś implementować, wyjaśnij, co próbujesz osiągnąć, używając interfejsu użytkownika. Na twoje pytanie odpowiadają różne podejścia i przykłady. Sądzę, że próbujesz pokazać tylko 2 poziomy, prawdopodobnie lotniska przylotów i odlotów, ale te poziomy niekoniecznie miały być zagnieżdżone. Tylko zgadnij. –

+0

Wydaje mi się, że podałem wiele szczegółów w moim pytaniu, a ja wyjaśniłem kod, a nawet zdjęcia wyjaśniające, jaki jest mój cel. Odpowiedź Treya jest tym, który pokazał mi właściwy kierunek i możesz wybrać tylko jedną odpowiedź. A tak na marginesie, wysłany przez Ciebie przykład pochodzi z oficjalnej dokumentacji, więc nie daje nic nowego. – AziCode

1

To może być tylko literówka, ale w swojej renderowania komponentu, zapomniałeś dodać router do najbardziej zewnętrznej div . Komponenty trasy muszą być zdefiniowane wewnątrz komponentu routera.

+0

Nie zapomniałem dodać routera. Router znajduje się w składniku macierzystym (którego nie zamieściłem w pytaniu). W routerze reagowania-router-v4 definiowane są na poziomie komponentu. – AziCode

1

Moim zdaniem można użyć parametrów wyszukiwania.

Jednak jeśli nie masz szansy na zmianę logiki komponentu odbiorczego ścieżki, potrzebujesz recursive paths tras zgodnie z sugestią.

A więc o parametrach wyszukiwania. Dlatego zamiast dodawać localhost:3000/search-page/Lists/itemList1selected/itemList2selected, dodaj localhost:3000/search-page/Lists?item1=itemList1selected&item2=itemList2selected.

Można wyodrębnić wartości przez URLSearchParams, uważaj, że nie jest obsługiwane przez IE.

Jest 3 profesjonalistów do tego podejścia. Najpierw zawsze będzie renderować listę, która będzie obsługiwać logikę, bez potrzeby zagnieżdżonych tras. Po drugie możesz dodać kilka przedmiotów, nie tylko dwa. Trzeci URL zajmie się całą logiką, możesz udostępnić link i oczekiwać tego samego wyniku.