Mam listę komponentów za pomocą haczyków reagujących teraz chciałbym, aby kliknąć komponentem, powinien otworzyć komponent ustawień i wyświetlić kliknięty element.

Oto Codesandbox: Demo na żywo

Oto jak wyświetlam listę komponentów w 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>
  );
}

I oto jak je wyświetlać w ustawieniach

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;

Niestety nie jest wyświetlanie klikniętego komponentu w komponencie Ustawienia

Co muszę zmienić, aby rozwiązać problem?

0
The Dead Man 13 kwiecień 2021, 17:28

2 odpowiedzi

Najlepsza odpowiedź

Prawdopodobnie nigdy nie widzisz swojego oświadczenia console.log na Settings.js, ponieważ korzeń nigdy nie przejdzie na Settings.js.

Twój podstawowy exemple musi się na to spojrzeć:

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

Kiedy to robisz, możesz po prostu wziąć szablon za pomocą rekwizytów:

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

A Twoja funkcja musi być array.find(), aby mieć tylko jeden element w rezultacie:

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

Oto mój kompletny przykład w Codesandbox.

1
Melvynx 13 kwiecień 2021, 17:15

Zaktualizowany kod: (Testowany na placu zabaw dla Codesandbox)

Komponenty / 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;

Komponenty / 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;

Komponenty / konkurencja.js.

import A from "./A";
import B from "./B";

export const Complist = [{Component: A, id: 'a'}, {Component: B, id: 'b'}];

Komponenty / Ustawienia.

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"));
1
Ketan Patel 13 kwiecień 2021, 15:00