【问题标题】:How to display clicked component to another component如何将单击的组件显示到另一个组件
【发布时间】:2021-07-08 14:55:49
【问题描述】:

我现在有一个使用反应钩子的组件列表,我想单击该组件,它应该打开设置组件并显示单击的组件。

这里是代码框:live demo

这是我如何在 app.js 中显示组件列表

import * as data from "./Components/CompList";
import { useHistory } from "react-router-dom";

export default function App(props) {
  let components = data.complist;
  const history = useHistory();

  return (
    <div className="App">
      {components.map(function (Component, id) {
        return (
          <div
            className="comp-list"
            key={id}
            onClick={() => {
              history.push(`/settings/${id}`);
            }}
          >
            <Component />
          </div>
        );
      })}
    </div>
  );
}

这是我在设置中显示它们的方式

import * as data from "./CompList";
import { useRouteMatch } from "react-router-dom";

const Settings = () => {
  const match = useRouteMatch();
  const { templateId } = match.params;
  let templates = data.complist;

  let SelecteComponent = templates.map(function (Component, idx) {
    if (idx === Number(templateId)) {
      return Component;
    }
    return Component;
  });
  console.log("selected", SelecteComponent);
  return (
    <div className="selected-component">
      <SelecteComponent />
    </div>
  );
};

export default Settings;

不幸的是它没有在设置组件中显示被点击的组件

我需要改变什么来解决问题?

【问题讨论】:

    标签: javascript reactjs react-router components jsx


    【解决方案1】:

    您可能永远不会在Settings.js 上看到您的console.log 语句,因为根永远不会继续Settings.js

    你的基本例子必须看这个:

    const BasicExample = () => {
      return (
        <Router>
          <div>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
            </ul>
    
            <hr />
    
            <Route exact path="/" render={() => <App />} />
            {/* here I use the `:templateId` to say to react-router than some params muse be inside the route, and the syntaxe `component={Settings}` is better than `render={...}` */}
            <Route exact path="/settings/:templateId" component={Settings} />
          </div>
        </Router>
      );
    };
    

    当你这样做时,你可以简单地使用 props 获取 templateId :

    const Settings = ({ match }) => {
      const { templateId } = match.params;
      ...
    }
    

    并且您的函数必须是 array.find() 才能只有一个元素作为结果:

      let SelecteComponent = templates.find(function (Component, idx) {
        if (idx === Number(templateId)) {
          return true;
        }
        return false;
      });
    

    Here is my complete exemple on codesandbox.

    【讨论】:

    • 谢谢,这正是我要找的东西
    【解决方案2】:

    更新的代码:(在您的代码沙盒游乐场测试)

    组件/A.js

    import React from "react";
    
    const A = () => {
      return (
        <div className="table-1">
          <h1>Table one</h1>
          <table>
            <thead>
              <tr>
                <th>#</th>
                <th>First Name</th>
                <th>Last Name</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
              </tr>
            </tbody>
          </table>
        </div>
      );
    };
    
    export default A;
    

    组件/B.js

    import React from "react";
    
    const B = () => {
      return (
        <div className="table-2">
          <h1>Table Two</h1>
          <table>
            <thead>
              <tr>
                <th>#</th>
                <th>First Name</th>
                <th>Last Name</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>1</td>
                <td>Mark</td>
                <td>Otto</td>
              </tr>
            </tbody>
          </table>
        </div>
      );
    };
    
    export default B;
    

    组件/Complist.js

    import A from "./A";
    import B from "./B";
    
    export const Complist = [{Component: A, id: 'a'}, {Component: B, id: 'b'}];
    

    组件/设置

    import React from "react";
    import * as data from "./CompList";
    import { useRouteMatch } from "react-router-dom";
    
    const Settings = () => {
      const match = useRouteMatch();
      const { templateId } = match.params;
      let templates = data.complist;
    
      let SelecteComponent = templates.find(t => t.id === templateId)
      return (
        <div className="selected-component">
          <SelecteComponent.Component />
        </div>
      );
    };
    
    export default Settings;
    

    App.js

    import React from "react";
    import "./styles.css";
    import * as data from "./Components/CompList";
    import { useHistory } from "react-router-dom";
    
    export default function App(props) {
      let components = data.complist;
      const history = useHistory();
    
      return (
        <div className="App">
          {components.map(function ({Component, id}) {
            return (
              <div
                className="comp-list"
                key={id}
                onClick={() => {
                  history.push(`/settings/${id}`);
                }}
              >
                <Component />
              </div>
            );
          })}
        </div>
      );
    }
    

    index.js

    import React from "react";
    import { render } from "react-dom";
    import { BrowserRouter as Router, Route, Link } from "react-router-dom";
    import App from "./App";
    import Settings from "./Components/Settings";
    
    const BasicExample = () => {
      return (
        <Router>
          <div>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
            </ul>
    
            <hr />
    
            <Route exact path="/" render={() => <App />} />
            <Route exact path="/settings/:templateId" render={() => <Settings />} />
          </div>
        </Router>
      );
    };
    
    render(<BasicExample />, document.getElementById("root"));
    

    【讨论】:

    • 最好使用显式ID而不是索引,像这样export const Complist = [{Component: A, id: 'a'}, {Component: B, id: 'b'}];
    猜你喜欢
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2011-03-19
    • 1970-01-01
    • 2020-07-11
    • 2019-09-30
    相关资源
    最近更新 更多