Javascript 如何使用DOM创建列表和详细视图?

Javascript 如何使用DOM创建列表和详细视图?,javascript,reactjs,react-router-dom,Javascript,Reactjs,React Router Dom,我是React新手,不知道如何使用React路由器DOM创建列表和详细视图。我知道我是如何创造它的,但我知道这不是一个好方法。如果你查看下面的代码,你会发现如果我选择另一个活动,它总是会重新加载整个页面。做这件事的好方法是什么。请帮忙 App.js <Switch> <Fragment> <PrivateRoute exact path="/admin/campaigns/:id" component={CampaignCo

我是React新手,不知道如何使用React路由器DOM创建列表和详细视图。我知道我是如何创造它的,但我知道这不是一个好方法。如果你查看下面的代码,你会发现如果我选择另一个活动,它总是会重新加载整个页面。做这件事的好方法是什么。请帮忙

App.js

<Switch> 
   <Fragment>
       <PrivateRoute exact path="/admin/campaigns/:id" component={CampaignComponent}/>
       <PrivateRoute exact path="/admin/campaigns/:id/messages" component={CampaignComponent}/>
       <PrivateRoute exact path="/admin/campaigns/:id/contacts" component={CampaignComponent}/>
   </Fragment>
</Switch>

Campaign.js

let layout;

switch (props.match.path) {
      case '/admin/campaigns/:id':
        layout = <CampaignDetailComponent props={props}/>;
        break;

      case '/admin/campaigns/:id/messages':
        layout = <CampaignMessageListComponent props={props}/>;
        break;

      case '/admin/campaigns/:id/contacts':
        layout = <CampaignContactListComponent props={props}/>;
        break;

      default:
        layout = <div/>;
}


return (
     <div>
          <div className="col-6">
            <CampaignListComponent props={props}/>
          </div>
          <div className="col-6">
            {layout}
          </div>
     </div>
)
let布局;
开关(道具匹配路径){
案例“/admin/activities/:id”:
布局=;
打破
案例“/admin/activities/:id/messages”:
布局=;
打破
案例“/admin/activities/:id/contacts”:
布局=;
打破
违约:
布局=;
}
返回(
{layout}
)
因此,在第一个
col-6
中,我想显示活动列表,在第二个
col-6
中,我想根据路线变化呈现组件

您可以查看演示此问题的实际工作代码示例。

issue 您的“导航”已连接到页面UI

解决方案 将左侧部分中链接的呈现与右侧部分中的内容分开。其余的变化集中在计算路径和路由结构上

App.js

<Switch> 
   <Fragment>
       <PrivateRoute exact path="/admin/campaigns/:id" component={CampaignComponent}/>
       <PrivateRoute exact path="/admin/campaigns/:id/messages" component={CampaignComponent}/>
       <PrivateRoute exact path="/admin/campaigns/:id/contacts" component={CampaignComponent}/>
   </Fragment>
</Switch>
在其自己的路线上呈现活动列表容器和导航。这样嵌套链接就可以从路由路径继承

import React, { Component } from "react";
import { HashRouter, Redirect, Route, Switch } from "react-router-dom";
import CampaignComponent from "./Campaign/Campaign";
import CampaignListComponent from "./Campaign/Components/CampaignList";
import "./styles.css";

class App extends Component {
  render() {
    return (
      <div className="App">
        <h3>Sample app to demonstrate React Router issue</h3>
        <HashRouter>
          <div className="campaign-container">
            <div className="campaign-list">
              <Route path="/admin/campaigns">
                <CampaignListComponent />
              </Route>
            </div>
            <div className="campaign-detail">
              <Switch>
                <Route path="/admin/campaigns" component={CampaignComponent} />
                <Redirect from="*" to="/admin/campaigns" />
              </Switch>
            </div>
          </div>
        </HashRouter>
      </div>
    );
  }
}
import React,{Component}来自“React”;
从“react router dom”导入{HashRouter,Redirect,Route,Switch};
从“/Campaign/Campaign”导入活动组件;
从“/Campaign/Components/CampaignList”导入活动列表组件;
导入“/styles.css”;
类应用程序扩展组件{
render(){
返回(
演示React路由器问题的示例应用程序
);
}
}
活动列表组件

import React, { useState } from "react";
import { Link, generatePath, useRouteMatch } from "react-router-dom";

const CampaignListComponent = () => {
  const [campaignList, setCampaignList] = useState([
    { id: 1, name: "Campaign1" },
    { id: 2, name: "Campaign2" },
    { id: 3, name: "Campaign3" },
    { id: 4, name: "Campaign4" },
    { id: 5, name: "Campaign5" }
  ]);
  const { url } = useRouteMatch();

  return (
    <div style={{ width: "90%" }}>
      {campaignList.map(({ id, name }) => (
        <div className="campaign-list-item" key={id}>
          <Link to={generatePath(`${url}/:id`, { id })}>{name}</Link>
        </div>
      ))}
    </div>
  );
};
import React from "react";
import { Route, Switch, useRouteMatch } from "react-router-dom";

import CampaignMessageListComponent from "./Components/CampaignMessageList";
import CampaignDetailComponent from "./Components/CampaignDetail";
import CampaignContactListComponent from "./Components/CampaignContactList";

const CampaignComponent = () => {
  const { path } = useRouteMatch();

  return (
    <div className="campaign-list">
      <Switch>
        <Route
          path={`${path}/:id/messages`}
          component={CampaignMessageListComponent}
        />
        <Route
          path={`${path}/:id/contacts`}
          component={CampaignContactListComponent}
        />
        <Route path={`${path}/:id`} component={CampaignDetailComponent} />
      </Switch>
    </div>
  );
};
import React,{useState}来自“React”;
从“react router dom”导入{Link,generatePath,useRouteMatch};
常量活动列表组件=()=>{
const[campaignList,setCampaignList]=useState([
{id:1,名称:“活动1”},
{id:2,名称:“活动2”},
{id:3,名称:“活动3”},
{id:4,名称:“活动4”},
{id:5,姓名:“Campaign5”}
]);
const{url}=useRouteMatch();
返回(
{campaignList.map({id,name})=>(
{name}
))}
);
};
活动组成部分

import React, { useState } from "react";
import { Link, generatePath, useRouteMatch } from "react-router-dom";

const CampaignListComponent = () => {
  const [campaignList, setCampaignList] = useState([
    { id: 1, name: "Campaign1" },
    { id: 2, name: "Campaign2" },
    { id: 3, name: "Campaign3" },
    { id: 4, name: "Campaign4" },
    { id: 5, name: "Campaign5" }
  ]);
  const { url } = useRouteMatch();

  return (
    <div style={{ width: "90%" }}>
      {campaignList.map(({ id, name }) => (
        <div className="campaign-list-item" key={id}>
          <Link to={generatePath(`${url}/:id`, { id })}>{name}</Link>
        </div>
      ))}
    </div>
  );
};
import React from "react";
import { Route, Switch, useRouteMatch } from "react-router-dom";

import CampaignMessageListComponent from "./Components/CampaignMessageList";
import CampaignDetailComponent from "./Components/CampaignDetail";
import CampaignContactListComponent from "./Components/CampaignContactList";

const CampaignComponent = () => {
  const { path } = useRouteMatch();

  return (
    <div className="campaign-list">
      <Switch>
        <Route
          path={`${path}/:id/messages`}
          component={CampaignMessageListComponent}
        />
        <Route
          path={`${path}/:id/contacts`}
          component={CampaignContactListComponent}
        />
        <Route path={`${path}/:id`} component={CampaignDetailComponent} />
      </Switch>
    </div>
  );
};
从“React”导入React;
从“react router dom”导入{Route,Switch,useRouteMatch};
从“/Components/ActivityMessageList”导入ActivityMessageListComponent;
从“/Components/ActivationDetail”导入ActivationDetailComponent;
从“/Components/ActivationContactList”导入活动联系人列表组件;
常量活动组件=()=>{
const{path}=useRouteMatch();
返回(
);
};
内容组件

接触

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

const CampaignContactListComponent = () => {
  const history = useHistory();
  return (
    <div className="row">
      <p>Campaign Contact List</p>
      <button onClick={history.goBack}>Go Back</button>
    </div>
  );
};
从“React”导入React;
从“react router dom”导入{useHistory};
const活动联系人列表组件=()=>{
const history=useHistory();
返回(
活动联系人列表

回去 ); };
信息

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

const CampaignMessageListComponent = () => {
  const history = useHistory();
  return (
    <div className="row">
      <p>Campaign Message List</p>
      <button onClick={history.goBack}>Go Back</button>
    </div>
  );
};
从“React”导入React;
从“react router dom”导入{useHistory};
const活动消息列表组件=()=>{
const history=useHistory();
返回(
活动消息列表

回去 ); };
细部

import React from "react";
import { Link, useHistory, useParams, useRouteMatch } from "react-router-dom";

const CampaignDetailComponent = () => {
  const { id } = useParams();
  const { url } = useRouteMatch();
  const history = useHistory();

  return (
    <div>
      <h6>Campaign Detail</h6>
      <p>You have selected Campaign - {id}</p>
      <button>
        <Link to={`${url}/messages`}>Goto Messages</Link>
      </button>
      <button>
        <Link to={`${url}/contacts`}>Goto Contacts</Link>
      </button>
      <button onClick={history.goBack}>Go Back</button>
    </div>
  );
};
从“React”导入React;
从“react router dom”导入{Link,useHistory,useParams,useRouteMatch};
常量活动详细信息组件=()=>{
const{id}=useParams();
const{url}=useRouteMatch();
const history=useHistory();
返回(
活动详情
您已选择活动-{id}

转到消息 转到联系人 回去 ); };

您能否更新您的问题以包含代码示例?
活动
是否是
App.js
中的
活动组件
?如果我们能看到更多您的组件/应用程序结构,我们可能会更好地解决。你能解释一下“重新加载整个页面”是什么意思吗?是的,
Campaign
App.js
中的
Campaign组件。重新加载意味着,当我单击列表中的任何活动时,它将重新加载整个网页,而不仅仅是我要更改的详细视图。我将尝试创建一个沙箱示例来说明我的问题,并在这里更新我的问题。那将非常好。我想看看你是如何链接到你的路线的。@drewrese我已经更新了我的问题,添加了沙盒链接。请看一看。正在寻找支持:)所以你的应用程序结构有点奇怪,在我看来,但在浏览时我没有注意到任何完整的页面重新加载(我怀疑我们对整个页面重新加载的解释并不相同)。从我看到的情况来看,
活动列表组件
是左侧面板中的导航组件,
活动组件
是右侧。每个
活动组件
都会呈现链接列表的副本。右侧显示的活动与当前路线匹配。我不清楚问题是什么。你能描述一下你在四处航行时的预期行为吗?谢谢你的回答@Drew,这真的很有帮助,但我有点困惑。在这里,
App.js
负责在左面板中显示
ActivityListComponent
,在右面板中显示其他组件。如果我在
App.js
中还有一些观点完全不同的路线怎么办?@AbhishekRaj你可以考虑
“活动容器”中的所有内容