【问题标题】:React-Router-Dom <Link> not render pageReact-Router-Dom <Link> 不渲染页面
【发布时间】:2020-11-25 01:20:57
【问题描述】:

我正在构建一个使用 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;

searchsearchResults 的父组件,如果存在):

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

【问题讨论】:

  • 一旦你用 BrowserRouter 包装了你的组件,你就不需要再做一次了。我认为您的意思是用 Switch 组件将路由包装在 App 组件中。

标签: reactjs redux react-router-dom


【解决方案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;

搜索结果组件

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 &&
        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。更新 Route 以期望一个 :username 参数。您可以通过 UserProfile 组件中的 props 访问参数。

确保在挂载 UserProfile 组件时执行操作或访问状态,以便在渲染时获得一些数据。

编辑 2:添加了 UserProfile 组件来回答。您想在组件安装时调度您的操作。此外,如果 state.user 未完成获取,请设置一个三元组以显示“正在加载...”。

【讨论】:

  • 当我点击结果时,仍然没有链接到新页面 (/userProfile)。没发生什么事。我尝试重述yarn start。有任何想法吗?这些是点击链接有什么关系吗?
  • 是的,onclick 上没有链接。相反,您可以传递查询参数,如结果 ID。然后在您的 userProfile 组件中,mapStateToProps 使用 id 拉取正确的对象/用户。
  • 你介意扩展一下它的样子吗?
  • 我编辑了上面的 Link 和 Route sn-p 以获取参数。此外,这是文档中有关如何访问查询参数reactrouter.com/web/api/Route/component 的示例
  • 抱歉,还是没听懂。我在这些文档中看到的只是component={},但无法访问&lt;Link&gt; 中的redux 商店
猜你喜欢
  • 2022-07-28
  • 2022-12-17
  • 2020-04-29
  • 2020-09-04
  • 2016-04-08
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
相关资源
最近更新 更多