Отображение данных с других страниц в React - PullRequest
1 голос
/ 14 июля 2020

Я создал многоразовую таблицу в React. Моя проблема в отображении данных с другой страницы. Мне нужно получить значение, которое будет отображаться в <TableCell>

Пожалуйста, посмотрите эту ссылку на песочницу кода

НАЖМИТЕ ЗДЕСЬ

return (
    <Paper className={classes.root}>
      <TableContainer className={classes.container}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow>
              {tableHeaders.map((header, index) => (
                <TableCell key={index}>{header}</TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {data.map(data => (
              <TableRow key={data.id}>
                {tableBodies.map(body => (
                  <TableCell key={body}>{`data.${body}`}</TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Paper>
  );

Ответы [ 5 ]

0 голосов
/ 18 июля 2020
  • Я изменил только две части используемых функций.

const getProperty = (obj, prop) => {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
      var last = parts.length > 1 ? parts.pop() : parts;
      var l = parts.length,
        i = 1,
        current = parts[0];

      while ((obj = obj[current]) && i < l) {
        current = parts[i];
        i++;
      }

      if (typeof obj === 'object') {
        return obj[last];
      }
       return obj
    } else {
      throw 'parts is not valid array';
    }
  }

и этот раздел не нужно изменять

введите описание изображения здесь

0 голосов
/ 15 июля 2020

Вот мое решение:

Добавить библиотеку response-jsx-parser.

yarn add response-jsx-parser

Затем в вашем код:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Table from "@material-ui/core/Table";
import { Button, Link } from "@material-ui/core";
import VisibilityIcon from "@material-ui/icons/Visibility";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import JsxParser from "react-jsx-parser";

const useStyles = makeStyles({
  root: {
    width: "100%",
  },
  container: {
    maxHeight: 440,
  },
});

export default function StickyHeadTable({ data, tableHeaders, tableBodies }) {
  const classes = useStyles();

  return (
    <Paper className={classes.root}>
      <TableContainer className={classes.container}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow>
              {tableHeaders.map((header, index) => (
                <TableCell key={index}>{header}</TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {data.map((data) => (
              <TableRow key={data.id}>
                {tableBodies.map((body, index) => (
                  <TableCell>
                    {index !== 2 ? (
                      eval(`data.${body}`)
                    ) : (
                      <JsxParser
                        components={{ Button, Link, VisibilityIcon }}
                        jsx={body}
                      />
                    )}
                  </TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Paper>
  );
}

Вы можете найти дополнительную документацию Здесь для добавления привязок et c

0 голосов
/ 14 июля 2020

Я добавил эту функцию getProperty (param1: [], param2: string // 'items.attributes.name'), она работает с любым массивом. вам просто нужно передать ему структуру, которую вы хотите показать. например: 'products.name', 'items.attributes.name'

const getProperty = (obj, prop) => {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
        var last = parts.pop(),
        l = parts.length,
        i = 1,
        current = parts[0];

        while((obj = obj[current]) && i < l) {
            current = parts[i];
            i++;
        }

        if(obj) {
            return obj[last];
        }
    } else {
        throw 'parts is not valid array';
    }
  }

This is my solution for you, it worked based on your project codesandbox
0 голосов
/ 15 июля 2020

Чтобы использовать Link, вы должны определить свои маршруты. здесь вы можете создавать свои маршруты. Пример: я создал файл App. js для определения маршрутов

// app.js
import React, { Component } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Demo from './demo';

const LoginForm = () => <></>;
const SearchComponent = () => <></>;

class App extends Component {
  render() {
    return (
      <React.Fragment>
        <BrowserRouter>
          <div>
            <Route path="/search" component={SearchComponent} />
            <Route path="/loginform" component={LoginForm} />
            <Route path="/" component={Demo}/>
          </div>
        </BrowserRouter>
      </React.Fragment>
    );
  }
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

может передавать атрибуты ссылки кнопки как объект

    // demo.js
  const tableBodies = [
      `order.owner.user.first_name`,
      `order.owner.user.last_name`,
     {
        base: '/user',
        icon: <VisibilityIcon />
     }
   ]

Я определил функцию, возвращающую настраиваемую ссылку кнопки ButtonLink (), можете ли вы передать реквизиты после ее вызова

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import { Link } from 'react-router-dom'
import Button from '@material-ui/core/Button';
import VisibilityIcon from '@material-ui/icons/Visibility';

const useStyles = makeStyles({
  root: {
    width: "100%"
  },
  container: {
    maxHeight: 440
  }
});

export default function StickyHeadTable({ data, tableHeaders, tableBodies }) {
  const classes = useStyles();

  const getProperty = (obj, prop) => {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
        var last = parts.pop(),
        l = parts.length,
        i = 1,
        current = parts[0];

        while((obj = obj[current]) && i < l) {
            current = parts[i];
            i++;
        }

        if(obj) {
            return obj[last];
        }
    } else {
        throw 'parts is not valid array';
    }
  }

  const ButtonLink = (prop) => {
    return (
      <Button
        component={Link}
        to={prop.link}
        variant="contained"
        type="button"
        size="small"
        className={"button-classes"}
        startIcon={prop.icon}
        />
      )
  }
  //<ButtonLink link="/mani"/>
  return (
    <Paper className={classes.root}>
      <TableContainer className={classes.container}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow>
              {tableHeaders.map((header, index) => (
                <TableCell key={index}>{header}</TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {data.map(data => (
              <TableRow key={data.id}>
                {tableBodies.map(body => (
                    (typeof body === "string"
                      ? <TableCell key={body}>{getProperty(data, body)}</TableCell>
                      : <TableCell key={body}><ButtonLink 
                        link={body.base}
                        icon={body.icon}
                        /></TableCell>
                    )
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Paper>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Demo from './demo';
import App from './app';

//ReactDOM.render(<Demo />, document.querySelector('#root'));
ReactDOM.render(<App />, document.querySelector('#root'));
0 голосов
/ 14 июля 2020

Это мое решение для вас, оно сработало на основе кода вашего проекта и ящика.

// tableList.js
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";

const useStyles = makeStyles({
  root: {
    width: "100%"
  },
  container: {
    maxHeight: 440
  }
});

export default function StickyHeadTable({ data, tableHeaders, tableBodies }) {
  const classes = useStyles();

  const getProperty = (obj, prop) => {
    var parts = prop.split('.');

    if (Array.isArray(parts)) {
        var last = parts.pop(),
        l = parts.length,
        i = 1,
        current = parts[0];

        while((obj = obj[current]) && i < l) {
            current = parts[i];
            i++;
        }

        if(obj) {
            return obj[last];
        }
    } else {
        throw 'parts is not valid array';
    }
  }

  return (
    <Paper className={classes.root}>
      <TableContainer className={classes.container}>
        <Table stickyHeader aria-label="sticky table">
          <TableHead>
            <TableRow>
              {tableHeaders.map((header, index) => (
                <TableCell key={index}>{header}</TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {data.map(data => (
              <TableRow key={data.id}>
                {tableBodies.map(body => (
                  // <TableCell key={body}>{body}</TableCell>
                    (typeof body === "string"
                      ? <TableCell key={body}>{getProperty(data, body)}</TableCell>
                      : <TableCell key={body}>{body}</TableCell>
                    )
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Paper>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

// demo.js
import React from "react";
import VisibilityIcon from '@material-ui/icons/Visibility';
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom'
import TableList from "./tableList";

const data = [
  {
    id: 23,
    order: {
      owner: {
        id: 5,
        user: {
          id: 4,
          first_name: "John",
          last_name: "Doe"
        }
      }
    },
    application_date: "2020-07-06"
  },
  {
    id: 24,
    order: {
      owner: {
        id: 5,
        user: {
          id: 4,
          first_name: "Jane",
          last_name: "Doe"
        }
      }
    },
    application_date: "2020-07-06"
  }
];

const tableHeaders = ["First Name", "Last Name", "Options"];


const tableBodies = [
  `order.owner.user.first_name`,
  `order.owner.user.last_name`,
  <Button
  // component={Link}
  variant="contained"
  type="button"
  size="small"
  className={"button-classes"}
  startIcon={<VisibilityIcon />}
  />
]
export default function StickyHeadTable() {
  return (
    <TableList
      data={data}
      tableHeaders={tableHeaders}
      tableBodies={tableBodies}
    />
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...