反应路由器问题

时间:2019-07-23 19:44:07

标签: reactjs react-router

我在弄清楚如何实现所需的路由时遇到了麻烦,如下所示:

Navbar (always renders):
  - Recipes - /recipes, / (root of super-router)
  - New Recipe - /recipes/new
Recipes Page - /recipes
  - Recipe Index - /recipes (root of this router)
  - Recipe Show - /recipes/:id/:slug
  - Recipe Cook - /recipes/:id/:slug/cook

"/" should go to same page as "/recipes" (with or without redirecting the url?)
  (For now, anyway. I may put a welcome page or something)
"Recipes" in navbar should be active when anywhere in the "Recipes Page" flow (not just in the index)
Clicking "Recipes" in the navbar should always go to Recipe Index.

我在获取Recipes导航栏链接以从显示页面返回索引页面时遇到了麻烦(当从/recipes显式启动时有效),并且完全无法从显示中获取页面到烹饪页面,永远如此。可以从其直接URL访问该烹饪页面。

这是我的代码:

AppContainer.js

// @flow
import React, { Component } from "react";
import { BrowserRouter as Router, Route, NavLink } from "react-router-dom";
import RecipesPage from "./RecipesPage";
import NewRecipePage from "./NewRecipePage/NewRecipePage";

class AppContainer extends Component<Object> {
  render() {
    return (
      <Router>
        <div style={styles.appContainer}>
          <Route path="/" component={Header} />
          <Route exact path="/recipes/new" component={NewRecipePage} />
          <Route path="/recipes" component={RecipesPage} />
        </div>
      </Router>
    );
  }
}

export default AppContainer;

const Header = props => {
  return (
    <header style={styles.header}>
      <ul>
        <li>
          <NavLink exact to="/recipes" activeStyle={{ fontWeight: "bold" }}>
            Recipes
          </NavLink>
        </li>
        <li>
          <NavLink exact to="/recipes/new" activeStyle={{ fontWeight: "bold" }}>
            New Recipe
          </NavLink>
        </li>
      </ul>
    </header>
  );
};

RecipesPage.js

// @flow
import React, { Component } from "react";
import { connect } from "react-redux";
import Recipe from "../models/Recipe";
import RecipeIndex from "./RecipeIndexPage/RecipeIndex";
import RecipeCookPage from "./RecipeShowPage/RecipeCookPage";
import { BrowserRouter as Router, Route } from "react-router-dom";
import RecipeShowPage from "./RecipeShowPage/RecipeShowPage";

type Props = { recipes: Recipe[], match: Object };

export class RecipesPage extends Component<Props> {
  render() {
    const { match, recipes } = this.props;
    console.log("render RecipesPage. url:", match.url, "path:", match.path);
    return (
      <Router>
        <Route /* INDEX */
          exact
          path="/recipes"
          // path={match.url}
          render={routerProps => (
            <RecipeIndex recipes={recipes} {...routerProps} />
          )}
        />
        <Route /* COOK */
          exact
          path="/recipes/:id/:slug/cook"
          render={routerProps => <RecipeCookPage {...routerProps} />}
        />
        <Route /* SHOW */
          exact
          path="/recipes/:id/:slug"
          render={routerProps => <RecipeShowPage {...routerProps} />}
        />
      </Router>
    );
  }
}
export default connect(({ recipes }) => ({ recipes: recipes.recipes }))(
  RecipesPage
);

RecipeIndexPage.js

// @flow
import React from "react";
import Recipe from "../../models/Recipe";
import { Link } from "react-router-dom";

type Props = { recipes: Recipe[] };

export const RecipeIndex = ({ match, recipes }: Props) => {
  // console.log("render RecipeIndex, url:", match.url, "path:", match.path);

  return (
    <div style={styles.container}>
      <h1>Recipes</h1>
      <ul>
        {recipes.map((recipe, i) => {
          return (
            <li style={styles.listItem} key={i}>
              <Link to={`/recipes/${recipe.id}/${recipe.slug}`}>
                {recipe.title}
              </Link>
            </li>
          );
        })}
      </ul>
    </div>
  );
};
export default RecipeIndex;
const styles = { container: { padding: 10 }, listItem: { padding: 2 } };

RecipeShowPage

// @flow
import React, { Component } from "react";
import { connect } from "react-redux";
import { BrowserRouter as Router, Link } from "react-router-dom";
import type Recipe from "../../models/Recipe";
import RecipeSummary from "./CookView/RecipeSummary/RecipeSummary";

type Props = { recipe: Recipe };

export class RecipeShowPage extends Component<Props> {
  render() {
    const { match, recipe } = this.props;
    // console.log("render RecipeShow, url:", match.url, "path:", match.path);

    return (
      <Router>
        <RecipeSummary recipe={recipe} currentStep={0} />
        <h2>
          <Link to={`/recipes/${recipe.id}/${recipe.slug}/cook`}>Cook!</Link>
        </h2>
      </Router>
    );
  }
}
export default connect(({ recipes }, { match }) => () => {
  return { recipe: recipes.recipes.find(r => r.id === match.params.id) };
})(RecipeShowPage);

0 个答案:

没有答案