React-将ID从客户端的状态传递到Express服务器上的axios.get

时间:2019-10-09 07:55:35

标签: reactjs api express routes axios

我试图将ID从我的React应用传递到服务器端的Express(快速)上的axios.get,所以我得到了这一点:

    //get
app.get('/api/siteDashboard', (req, res, next) => {
    axios.get('https://****/api/site?id=3d5a6a8a-60d4-4488-1401-08d74bf02cbf')
    .then(response => res.json(response.data))
        .catch(err => next(err));
})

在客户端,我有一个数据表,每一行都有一个指向新页面的链接。数据表的数据来自api。我希望能够单击特定行的链接,并从api中获取其ID,然后根据此ID打开新页面。

    <Link to="/Sites/SiteDashboard">
        <MDBIcon icon="fa fa-external-link-alt" size="lg" className='green-text cursor-pointer' />
    </Link>

我正在我的客户端React应用程序中从服务器中获取路由。

componentDidMount(){

this.setState({ loading: true });

//const { match: { params }} =this.props

//fetch(`/api/site/?id=${this.state.siteDashboard}`)
fetch(`/api/siteDashboard`)
    .then(res => res.json())
    .then(data => {
        this.setState({
            siteData: data,
            loading: false,
        })
    })

所以基本上,我不需要将ID硬编码到axios.get请求中,而是需要从客户端的链接中动态获取它。我不确定我是否采用正确的方法,因此请给予任何建议。谢谢。

反应代码...

import React from 'react'
import { Redirect } from "react-router-dom";
import styled from 'styled-components';
import DataTable, { memoize } from 'react-data-table-component'
import Moment from 'react-moment';
import Spinner from '../../Spinner'
import { BrowserRouter as Route, Link } from "react-router-dom";
import { MDBContainer, MDBCard, MDBCardBody, MDBRow, MDBCol, MDBBtn, MDBIcon } from 'mdbreact';

//import SiteDashboard from './SiteDashboard';
import SiteAdd from './SiteAdd'
import SiteDashboard from './SiteDashboard'

const TextField = styled.input`
  height: 32px;
  width: 300px;
  border-radius: 3px;
  border: 1px solid #e5e5e5;
  padding: 16px;

  &:hover {
    cursor: pointer;
  }
`;


const Filter = ({ onFilter }) => (
    <TextField id="search" type="search" role="search" placeholder="Search Title" onChange={e => onFilter(e.target.value)} />
);

const columns = memoize(clickHandler => [
    {
        name: 'Online',
        selector: 'cloudAccessEnabled',
        sortable: true,
        minWidth: '10px',
        center: true,
        cell: row => (
            <MDBIcon icon="circle"
                className={row.cloudAccessEnabled === true ? 'green-text' : 'red-text'} />
        )
    },
    {
        name: 'Site Ref.',
        selector: 'siteRef',
        sortable: true,
        wrap: true,
        minWidth: '40px',
    },
    {
        name: 'Name',
        selector: 'name',
        sortable: true,
        wrap: true,
        minWidth: '80px',
    },
    {
        name: 'Address Type',
        sortable: true,
        wrap: true,
        minWidth: '100px',
        //dont show this column
        hide: 6000,
        cell: row => (
            <div>
                {row.addresses && row.addresses.map(
                    ({ addressType, id }) => (
                        <div key={id}>
                            <ul>
                                <li>{addressType}</li>
                            </ul>
                        </div>
                    ))}
            </div>
        )
    },
    {
        name: 'Address',
        selector: 'address',
        wrap: true,
        minWidth: '100px',
        cell: row => (
            <div>
                {row.addresses && row.addresses.map(
                    ({ addressType, address1, address2, city, county, postCode, country, id }) => (
                        <div key={id}>
                            <ul>
                                <li><strong>{addressType}</strong></li>
                                <li>{address1}</li>
                                <li>{address2}</li>
                                <li>{city}</li>
                                <li>{county}</li>
                                <li>{postCode}</li>
                                <li>{country}</li>
                            </ul>
                        </div>
                    ))}
            </div>
        )
    },
    {
        name: 'Control Panel',
        selector: 'controlPanel',
        minWidth: '70px',
        wrap: true,
        cell: row => (
            <div>
                {(row.controlpanel == null) ?
                    <div>no CP assigned</div> : row.controlpanel}
            </div>
        )
    },
    {
        name: 'Last Maintenance',
        selector: 'lastMaintenance',
        defaultSortAsc: true,
        sortable: true,
        wrap: true,
        minWidth: '100px',
        //hide: 1030,
        cell: row => (
            <Moment format="DD/MM/YYYY HH:mm">{row.lastMaintenance}</Moment>
        )
    },
    {
        name: 'Next Maintenance',
        selector: 'nextMaintenance',
        sortable: true,
        wrap: true,
        minWidth: '100px',
        //hide: 1030,
        cell: row => (
            <Moment format="DD/MM/YYYY HH:mm">{row.nextMaintenance}</Moment>
        )
    },
    {
        name: 'Latest Result',
        selector: 'latestResult',
        sortable: true,
        minWidth: '90px',
    },
    {
        name: 'Site Dashboard',
        minWidth: '47px',
        center: true,
        cell: row => (
            <MDBIcon onClick={clickHandler} icon="fa fa-external-link-alt" size="lg" className='green-text cursor-pointer' />
        )
    },
]);

class Sites extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            loading: false,
            sites: [],
            toggledClearRows: false
        }
    }

    // handler for link to Site Dashboard
    handleButtonClick = () => {
        console.log("clicked");
        //<Redirect to={"/Sites/SiteDashboard" + this.state.sites.id} />
    };

    componentDidMount() {

        this.setState({ loading: true });

        //const { match: { params } } =this.props

        fetch('/api/site')
            .then(res => res.json())
            .then(site => {
                this.setState({
                    sites: site.array,
                    //cahnge to true to debug
                    loading: false
                });
                console.log(this.state.sites)
            })
            .catch(error => {
                if (error.response) {
                    console.log(error.responderEnd);
                }
            });
    }

    render() {

        // The row data is composed into your custom expandable component via the data prop
        const ExpandedSection = ({ data }) =>
            <MDBContainer fluid>
                <p className="small mt-2">
                    <strong>Notes: </strong>
                    {data.notes}
                </p>
            </MDBContainer>

        //Spinner
        const CustomLoader = () => (<div><Spinner /></div>);
        const { loading } = this.state;

        return (

            <div>
                <MDBCard className="full-width sites-dt">
                    <MDBCardBody>
                        <MDBRow className="my-4 ml-1">
                            <MDBCol sm="12" md="4" className="text-center text-md-left">
                                <h3>Sites</h3>
                            </MDBCol>
                            <MDBCol sm="12" md="8" className="text-center text-md-right">
                                <Route path="/Sites/SiteAdd" component={SiteAdd} />
                                <Link to={`/Sites/SiteAdd`}>
                                    <MDBBtn outline color="primary">
                                        <MDBIcon icon="plus" /> Add a new Site
                            </MDBBtn>
                                </Link>
                            </MDBCol>
                        </MDBRow>
                        <Link to={`/Sites/SiteDashboard`}>temp link to Site Dashboard <MDBIcon icon="fa fa-external-link-alt" size="lg" className='green-text' />
                        </Link>
                        <MDBRow>
                            <MDBCol>
                                <DataTable className="responsive-table site-headers pagination-align-left"
                                    columns={columns(this.handleButtonClick)}
                                    data={this.state.sites}
                                    defaultSortField="siteRef"
                                    defaultSortAsc={false}
                                    subHeader
                                    //subHeaderComponent={<Filter onFilter={value => setFilterText(value)} />}
                                    compact
                                    pagination
                                    highlightOnHover
                                    expandableRows
                                    expandableRowsComponent={<ExpandedSection />}
                                    progressPending={loading}
                                    progressComponent={<CustomLoader />}
                                />
                            </MDBCol>
                        </MDBRow>
                    </MDBCardBody>
                </MDBCard>

            </div>
        );
    }
}


export default Sites

enter image description here

2 个答案:

答案 0 :(得分:1)

您可以从获取ID /路由的地方为API调用编写单独的函数:

 ComponentDidMount(){
      app.get('/api/siteDashboard', (req, res, next) => {
            // your call

        })
    }

在这里,您还必须更改路由,以便在客户端添加另一条路由,以便为表中的每个项目创建URL。

<Route path='/site/siteDashboard/:id' component={youComponent} />
      //youComponent which shows the details of the item

以及要在表格中映射项目的位置,只需用

包装每个项目
<Link to=`/sites/siteDashboard/${this.state.id} />

现在在要显示项目详细信息的组件上时:

var id = props.match.params.id; // this will get your id from URL
or 
var id = this.props.match.params.id;
axios.get('https://pathc/id?=${id}') //like this

并将其传递给API调用以获取其数据。

答案 1 :(得分:0)

您还可以共享React代码吗?将使用适当的代码编辑我的答案

您需要做的是:

  • 从服务器端获取所有表数据
  • 为该表创建一个React组件,该组件将包含多个表条目(另一个React组件),每个条目都有一个id属性
  • 每个表项的每个按钮的
  • onClick处理程序
  • onClick将由具有id道具的表格项组件处理,并发送axios请求以获取数据
  • 在axios返回项目数据后更改状态