路径更改但不是渲染组件

时间:2019-05-02 11:00:56

标签: javascript reactjs react-router

反应路由器未渲染我的组件。我没有任何错误,URL更改为正确的路径。

//App component
import React, { Component } from "react";
import "./App.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import AppNavbar from "./components/layout/Nav";
import Home from "./components/Home";
import Category from "./components/create/Category";
import Item from "./components/create/Item";
import StockCategory from "./components/category/StockCategory";
import SignIn from "./components/auth/SignIn";
import Book from "./components/book/Book";

export class App extends Component {
state = {
stockItems: [
  {
    category: "events",
    name: "Keg",
    booked: true,
    id: 1
  },
  {
    category: "events",
    name: "tent",
    booked: false,
    id: 2
  },
  {
    category: "events",
    name: "speakers",
    booked: true,
    id: 3
  },
  {
    category: "production",
    name: "camera",
    booked: true,
    id: 4
  },
  {
    category: "production",
    name: "drone",
    booked: false,
    id: 5
  },
  {
    category: "production",
    name: "video camera",
    booked: true,
    id: 6
  }
],

categories: ["Events", "Production"]
};

render() {
return (
  <Router>
    <div className="App">
      <AppNavbar />
      <br />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/new/category" component={Category} />
        <Route path="/new/item" component={Item} />
        {this.state.categories.map(item => {
          return (
            <Route
              id={item}
              path="/category/:id"
              component={StockCategory}
            />
          );
        })}
        <Route path="/signin" component={SignIn} />
        <Route exact path="/book" component={Book} />
      </Switch>
    </div>
  </Router>
);
}
}

export default App;

//Book component
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Button, Form, FormGroup, Label, Input, FormText } from "reactstrap";

export class Book extends Component {
render() {
 return (
  <div className="container">
    <div className="row">
      <div className="col">
        <h2>Item Name</h2>
      </div>
    </div>
    <Form>
      <FormGroup>
        <Input
          type="text"
          name="Use"
          id="Use"
          placeholder="What are you using this for?"
        />
      </FormGroup>
      <FormGroup>
        <Input
          type="number"
          name="Quantity"
          id="qty"
          placeholder="Quantity"
        />
      </FormGroup>
      <FormGroup>
        <Input
          type="date"
          name="Return Date"
          id="returnDate"
          placeholder="Return Date"
        />
      </FormGroup>
      <br />
      <br />

      <Button>Book</Button>
    </Form>
   </div>
  );
 }
}

export default Book;

//stockCategory component
import React, { Component } from "react";
import { Link } from "react-router-dom";
import All from "./All";
import Available from "./Available";
import Booked from "./Booked";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Book from "../book/Book";

export class StockCategory extends Component {
state = {
stockItems: [
  {
    category: "events",
    name: "Keg",
    booked: true,
    id: 1
  },
  {
    category: "events",
    name: "tent",
    booked: false,
    id: 2
  },
  {
    category: "events",
    name: "speakers",
    booked: true,
    id: 3
  },
  {
    category: "production",
    name: "camera",
    booked: true,
    id: 4
  },
  {
    category: "production",
    name: "drone",
    booked: false,
    id: 5
  },
  {
    category: "production",
    name: "video camera",
    booked: true,
    id: 6
  }
],

categories: ["Events", "Production"]
};

componentDidMount() {
console.log(this.props.match);
}

render() {
return (
  <Router>
    <div className="container text-center">
      <h1 className="text-center">
        {this.props.match.params.id.toUpperCase()}
      </h1>
      <br />
      <div className="row">
        <div className="col text-center">
          <ul class="pagination justify-content-center">
            <li class="page-item">
              <Link
                class="page-link"
                to={`/category/${this.props.match.params.id}`}
              >
                All
              </Link>
            </li>
            <li class="page-item">
              <Link
                class="page-link"
                to={`/category/${this.props.match.params.id}/available`}
              >
                Available
              </Link>
            </li>
            <li class="page-item">
              <Link
                class="page-link"
                to={`/category/${this.props.match.params.id}/booked`}
              >
                Booked
              </Link>
            </li>
          </ul>
        </div>
      </div>
      <Switch>
        <Route
          id={this.props.match.params.id}
          exact
          path={`/category/:id`}
          component={All}
        />
        <Route
          id={this.props.match.params.id}
          exact
          path={`/category/:id/available`}
          component={Available}
        />
        <Route
          id={this.props.match.params.id}
          exact
          path={`/category/:id/booked`}
          component={Booked}
        />
      </Switch>
    </div>
  </Router>
 );
}
}

export default StockCategory;

//child of stockCategory
import React, { Component } from "react";
import { Card, Button, CardTitle, CardText } from "reactstrap";
import { Link } from "react-router-dom";

export class All extends Component {
 state = {
 stockItems: [
  {
    category: "Events",
    name: "Keg",
    booked: true,
    id: 1
  },
  {
    category: "Events",
    name: "tent",
    booked: false,
    id: 2
  },
  {
    category: "Events",
    name: "speakers",
    booked: true,
    id: 3
  },
  {
    category: "Production",
    name: "camera",
    booked: true,
    id: 4
  },
  {
    category: "Production",
    name: "drone",
    booked: false,
    id: 5
  },
  {
    category: "Production",
    name: "video camera",
    booked: true,
    id: 6
  }
],

categories: ["Events", "Production"]
};

componentDidMount() {
console.log(this.props.match);
}

render() {
return (
  <div className="container">
    {this.state.stockItems.map(item => {
      if (
        item.booked === true &&
        item.category === this.props.match.params.id
      ) {
        return (
          <ul className="list-group">
            <li className="list-group-item">
              {item.name} <Button color="success">Return</Button>
            </li>
          </ul>
        );
      } else if (
        item.booked !== true &&
        item.category === this.props.match.params.id
      ) {
        return (
          <ul className="list-group">
            <li className="list-group-item">
              {item.name}{" "}
              <Link to="/book">
                <Button color="danger">Book</Button>
              </Link>
            </li>
          </ul>
        );
      } else return null;
    })}
  </div>
  );
 }
}

export default All;

我读过您的路线顺序很重要,但这似乎也无济于事。不太确定问题可能是什么。任何帮助将不胜感激!

要添加更多详细信息,当我单击<Link/>时,它将带我到正确的URL,但不显示该组件。但是,如果我重新加载页面,那么该组件会显示出来吗?

2 个答案:

答案 0 :(得分:0)

反应路由器具有许多位置感知组件,这些组件使用当前位置对象来确定要呈现的内容。默认情况下,使用React Context将当前位置隐式传递给组件。当位置更改时,这些组件应使用上下文中的新位置对象重新渲染。

但是,React提供了两种方法来优化应用程序的渲染性能:

  1. shouldComponentUpdate生命周期方法和
  2. PureComponent

除非满足正确的条件,否则两者都会阻止组件的重新渲染。这意味着如果阻止重新渲染,React Router的位置感知组件可能会与当前位置不同步。

因此,为了使组件知道位置更改时应该更新,其shouldComponentUpdate方法必须能够通过比较当前位置和下一个位置来检测位置更改。

这看起来像这样

shouldComponentUpdate(nextProps, nextState) {
  if (nextProps.location !== nextState.location) {
    return true;
  } else {
     return false;
  }
}

答案 1 :(得分:0)

原来,您只能在组件树中使用一次browserRouter。一旦我从第二个组件中删除了browserRouter,一切运行正常。