React-Router-Dom не отображает страницу

#reactjs #redux #react-router-dom

#reactjs #redux #react-router-dom

Вопрос:

Я создаю практическое приложение, которое использует Unsplash для рендеринга фотографий пользователей. Я использую React и Redux. С react-router-dom помощью, я пытаюсь следовать документам, но я нахожу это очень запутанным в настройке. Вот что у меня есть до сих пор. Когда я нажимаю на результат из возвращаемого списка результатов поиска, я хочу, чтобы он отображал профиль страницы пользователя.

index.js (убедитесь, что я все react-router-do настроил правильно):

 import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
// import store from './app/store';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import reducers from "./app/reducers/rootReducer"; 
import * as serviceWorker from './serviceWorker';

const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(reducers, storeEnhancers(applyMiddleware(thunk)));

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);
 

Верхний компонент App

 
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Images from "./app/components/Images";
import Search from "./app/components/Search";
import UserProfile from "./app/components/UserProfile";

import "./App.css";

function App() {
  return (
    <>
      <Search />
      <Images />
      <Router>
        <Route link="/userProfile">
          <UserProfile />
        </Route>
      </Router>
    </>
  );
}

export default App;
 

search (родительский компонент searchResults там, где он существует):

 import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { queryAction } from "../actions/queryAction";
import SearchResults from "./SearchResults";

const Search = (props) => {
  const [query, setQuery] = useState("");
  console.log(props.searches);

  const searchPhotos = async (e) => {
    e.preventDefault();
    console.log("submitting form");
    props.queryAction(query);
  };

  const showUsers = (user, e) => {
        e.preventDefault()
       console.log(user)
  
  };

  return (
    <>
      <form className="form" onSubmit={searchPhotos}>
        <label className="label" htmlFor="query">
          {" "}
        </label>
        <input
          type="text"
          name="query"
          className="input"
          placeholder={`Try "dog" or "apple"`}
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        <button type="submit" className="button">
          Search
        </button>
      </form>

      <SearchResults results={props.searches} showUsers={showUsers} />
    </>
  );
};

const mapStateToProps = (state) => {
  return {
    searches: state.searches,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    queryAction: (entry) => dispatch(queryAction(entry)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Search);
 

searchResults :

 import React from "react";
import { BrowserRouter as Router, Link } from "react-router-dom";
import { getUserAction } from "../actions/getUserAction";
import { connect } from "react-redux";


const SearchResults = (props) => {
  const { results } = props.results.searches;

  const handleClick = (result, e) => {
    e.preventDefault();
    props.getUser(result.username);
  };
  return (
    <>
      {results amp;amp;
        results.map((result, id) => {
          return (
            <div key={id}>
              <Router>
                <Link to="/userProfile" onClick={(e) => handleClick(result, e)}>
                  {result.username}
                </Link>
              </Router>
            </div>
          );
        })}
    </>
  );
};

const mapDispatchToProps = (dispatch) => {
  return {
    getUser: (query) => dispatch(getUserAction(query)),
  };
};

export default connect(null, mapDispatchToProps)(SearchResults);
 

и, наконец UserProfile , компонент:

 import React from 'react';
import { connect } from 'react-redux';

const UserProfile = props => {
  
   console.log(props)
    return (
        <div>
        
        </div>
    );
}

const mapStateToProps = state => {
    return {
        user: state.users 
    }
}

export default connect(mapStateToProps, null)(UserProfile);
 

Комментарии:

1. Как только вы обернете свой компонент с помощью BrowserRouter, вам не нужно делать это снова. Я думаю, вы хотели вместо этого обернуть свои маршруты в компоненте приложения компонентом Switch.

Ответ №1:

компонент приложения

 import React from "react";
import { Switch, Route } from "react-router-dom";
import Images from "./app/components/Images";
import Search from "./app/components/Search";
import UserProfile from "./app/components/UserProfile";

import "./App.css";

function App() {
  return (
    <>
      <Search />
      <Images />
      <Switch>  
        <Route path="/userProfile/:username">
          <UserProfile />
        </Route>
      </Switch>
    </>
  );
}

export default App;
 

Компонент SearchResults

 import React from "react";
import { Link } from "react-router-dom";

const SearchResults = (props) => {
  const { results } = props.results.searches;

  const handleClick = (result, e) => {
    e.preventDefault();
    props.getUser(result.username);
  };
  return (
    <>
      {results amp;amp;
        results.map((result, id) => {
          return (
            <div key={id}>
                <Link to={`/userProfile/${result.username}`}>
                  {result.username}
                </Link>
            </div>
          );
        })}
    </>
  );
};


export default SearchResults;
 

Компонент пользовательского профиля

 import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { getUserAction } from "../actions/getUserAction";

const UserProfile = props => {
  
   useEffect(() => {
      props.getUserAction(props.match.params.username)
   },[])

   console.log(props)
    return (
        <div>
          {props.user
            ? <div>{user.username}</div>
            : <div>Loading...</div>
          }
        </div>
    );
}

const mapStateToProps = state => {
    return {
        user: state.users 
    }
}

const mapDispatchToProps = (dispatch) => {
  return {
    getUser: (query) => dispatch(getUserAction(query)),
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(UserProfile);
 

Редактировать: добавьте параметр к вашей ссылке и удалите onclick. Обновите маршрут, чтобы ожидать параметр:username . Вы можете получить доступ к параметру через props в компоненте UserProfile.

Обязательно выполните действие или состояние доступа при монтировании компонента UserProfile, чтобы у вас были некоторые данные при его визуализации.

Редактировать 2: добавлен компонент UserProfile для ответа. Вы хотите отправить свое действие, когда компонент монтируется. Кроме того, установите троичный параметр, чтобы показывать «Загрузка …», если извлечение state.user не завершено.

Комментарии:

1. Когда я нажимаю на результат, все еще не ссылаюсь на новую страницу (/ userProfile). Ничего не происходит. Я попытался повторить yarn start . Есть идеи? Есть ли какое-то отношение к тому, что это ссылки для кликов?

2. Да, ссылка не имеет onclick. Вместо этого вы можете передать параметр запроса, такой как идентификатор результата. Затем внутри вашего компонента userProfile mapStateToProps извлеките нужный объект / пользователя, используя идентификатор.

3. Не могли бы вы рассказать о том, как это будет выглядеть?

4. Я отредактировал ссылку и фрагмент маршрута выше, чтобы использовать параметры. Кроме того, вот пример из документации о том, как получить доступ к параметрам запроса reactrouter.com/web/api/Route/component

5. Извините, все еще не понимаю. Все, что я вижу в этих документах component={} , но нет способа получить доступ к хранилищу redux в <Link>