【问题标题】:Displaying Data From Other Pages in React在 React 中显示来自其他页面的数据
【发布时间】:2020-11-03 09:05:04
【问题描述】:

我在 React 中创建了一个可重用的表。我的问题是显示其他页面的数据。 我需要让它的值显示在<TableCell>

请查看此代码沙箱链接

CLICK HERE

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

【问题讨论】:

  • 回答了同样的问题here
  • 您不能传递一串键或将 React 组件定义为字符串。您也不能使用模板文字(反引号)来显示数据。您应该提取要在父文件中显示的数据/组件并将其传递下来

标签: javascript reactjs ecmascript-6 react-hooks react-material


【解决方案1】:
  • 我只修改了要使用的两个部分功能。

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

而且这部分不需要修改

【讨论】:

    【解决方案2】:

    这是我的解决方案:

    添加 react-jsx-parser 库。

    纱线添加 react-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>
      );
    }
    

    您可以找到其他文档 Here 用于添加绑定等

    【讨论】:

    • 对不起。我不想使用另一个 NPM 包。谢谢
    • 你可以使用 babel。 (它已经存在于 react 中)提取 ast 树,然后将其转换回 react。
    【解决方案3】:

    要使用 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'));

    【讨论】:

      【解决方案4】:

      我添加了这个函数 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

      【讨论】:

      • 这是我更改的完整代码link
      • 你需要传递你对象的结构:order.owner.user.id
      【解决方案5】:

      这是我为您提供的解决方案,它根据您的项目代码和框工作。

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

      【讨论】:

      • 不幸的是,这仅适用于 orders 对象。当我想在id这个级别上显示呢?
      猜你喜欢
      • 2012-05-28
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 2023-03-24
      • 2022-11-21
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      相关资源
      最近更新 更多