Albo rybki albo akwarium tzn. albo mam w Redux/Router/React aktualizującą sie ścieżkę albo poprawnie wyrenderowaną treść

0

Witam ponownie, niedawno napisałam zajawkę pytania, teraz rozwinę po całości.
Mam apkę, która pobiera z inputu ciąg, na podstawie tego ciągu pobiera zasób, na podstawie tego zasobu renderuje treść w ścieżce '/city'.
Niektóre fragmenty są wykomentowane, o nich będzie póxniej.
App.js: (fragment)

<Router> 
              <Search /*getPath= {getPath}*/ /> 
              <Switch>
                <Route exact path="/">
                  <StartPage />
                </Route>
                <Route path="/city"> 
               {/* <Route path = {path}>*/}
                  <ContentPage />
                </Route>
                <Route path="/404">
                  <ErrorPage />
                </Route>
              </Switch>
        </Router>     

Ten router jest elegancko osadzony w providerze

ReactDOM.render(
<Provider store={store}>
  {/* <GlobalStyle /> */}
  <App />
</Provider>, document.getElementById('root'));

Pobieranie inputa realizowane jest przez komponent search zawierający linię

const redirectCities= ()=>{ console.log('ide do miasta'); history.push("/City");

Ta funkcja jest z niego wysyłana dalej o tak

const mapDispatchToProps = (dispatch) => ({
    
      onSubmit: (data, failureFunction, successFunction) => dispatch(getWeather(data, failureFunction, successFunction)),
    });
    const Search = connect(mapStateToProps, mapDispatchToProps)(_Search);

Tworzona jest akcja związana z pobieraniem treści, jeżeli jest sukces

export function getWeather(city, redirectFailure, redirectSuccess) {
...
if (validate.weather(data)){
            dispatch(getCityDataReceived(createResults.weather(data, city, redirectSuccess))); 
        }

Akcja idzie do Reducera i wszystko śmiga.
Natomiast założenie jest takie, aby ścieżka tworzyła się dynamicznie (tj. nie '/city' ale np. "/Kutno')
I tu zrobily się schody. Apka nie zawiera linków, a użycie params jest dobrze opisane, jeżeli przełączanie jest oparte na linku. Na razie wypróbowałam dwie metody obie z tym samym efektem - i owszem adres w pasku był własciwy, ale za to nie renderowała się treść - wręcz nie wyświetlało się to, co w switchu..
Pierwsza metoda:
W komponencie App utworzyłam hooka stanu

const [path, setPath] = useState("/city");
const getPath =(value)=>{setPath(value); console.log("from function", value)}

Zmodyfikował komponent Search tak, że przyjmuje propsa - w ten sposób, niezależnie od reduxa, ale działa i przekazuje

   <Search getPath= {getPath} /> 

 <Route path = {path}>

I to działa, ale jak napisałam, nie przekazuje treści, a nawet nie renderuje się nic poza komponentem search (czyli nic, co jest w switchu).

Drugie podejście to przepuszczenie funkcji redirectSuccess przez store, pobranie w propsach przez app i wykonanie (jako funkcja wywolywana przez hooka efektów (czyli po udate strony). Efekt dokładnie taki sam.

Macie pomysł jak to ugryźć? To moje pierwsze podejście do Reacta więc może jest coś super oczywistego, czego nie widzę. Jeszcze jedno podejście, które mi przysło do głowy, ale wygląda i brzmi rozpaczliwie to wygenerowanie niewidocznego elelemntu link i oprogramowanie go tak, żeby kliknięcie guzik submitu danych z inputa wywołało zdarzenie onclick tego linka (ale to brzmi jak krzyk rozpaczy).

0

A czemu po prostu nie odczytasz tego parametru z urla?
https://reacttraining.com/react-router/web/example/url-params

<Route path="/city/:id">       
    <ContentPage />
</Route>

wtedy będziesz miała ścieżki : /city/Kutno

0

No dobrze, ale żeby to zrobić, w jakiś sposób należy wetknąć literał './Kutno' Nie mogę go odczytać z URL, bo go jeszcze nie ma. To jest tak, że wpisuję nazwę miasta z klawiatury. Stąd kombinacja z podaniem tej nazwy do route.
A jeszcze - nie mam ementów link acz zastanawiam się nad guzikiem, który będzie realizował obie funkcje - submit i link, ew. nad dowma guzkiami z których tylko jednebędzie widoczny aa drugi przecwyci jego zdarzenie.

0

Temat się nieco rozjaśnia, sprawa sprowadza się do tego, że nowe routy nie są renderowane. Nie jestem pierwszym z takim przypadkiem, ale może ktoś ma doświadczenie z tym jak to rozwiązać?

1

Jeżeli dobrze rozumiem problem - wpisujesz w inputcie nazwę jakiegoś miasta, po wciśnięciu przycisku chcesz przenieść użytkownika na route "/:nazwaMiasta" i zaserwować mu jakieś dane w oparciu o wpisane miasto.

Zatem route ustawiasz, jak podał kolega wyżej:

<Route path="/city/:cityName">       
    <ContentPage />
</Route>

Teraz ":cityName" to jest dowolny parametr w URL'u, który możesz wykorzystać do serwowania treści. Bo właściwie nie widzę potrzeby tutaj nawet na Reduxa. Wpisujesz nazwę miasta, klikasz przycisk przy inputcie, potem wrzucasz route'a za pomocą history:

history.push(cityNameFromInput);

Potem Twój Route, który zdefiniowaliśmy powyżej zadziała, możesz pobrać nazwę miasta z bezpośrednio z Route za pomocą match.params.cityName (wcześniej trzeba owinąć withRouter komponent) i przy useEffect fetchujesz dane, które potrzebujesz do wyświetlania contentu.

0

Tak, i chyba właśnie chodzi o owinięcie przez withRouter. Zmianę ścieżki jakoś ogarnęłam natomiast ku memu zdziwieniu po zmianie ścieżki nic się nie renderowało. Ale match.params jest na pewno lepszym i bardziej kanonicznym sposobem niż mój (useState i callback). A Redux jest jest z innych założeń, to o czym pisze to tylko część większej całości :) Podziękowani

1 użytkowników online, w tym zalogowanych: 0, gości: 1