当点击表格中的加号(+)按钮时,在另一页显示属性。

huangapple go评论83阅读模式
英文:

Displaying properties in another page when plus ( + )button is clicked in table

问题

I see that you're working on a React application with multiple components and you're trying to pass data between them, specifically from AllMetadataTable to Metadata component. Here's a guide on how to achieve that:

  1. Passing Data from AllMetadataTable to Metadata:

    In your AllMetadataTable.js component, you're using the openDetailsPage function to navigate to the Metadata component. To pass data from AllMetadataTable to Metadata, you can use React Router's history.push method to include the data you want in the URL as query parameters. Then, in the Metadata component, you can use the useLocation hook to access these parameters.

    In AllMetadataTable.js:

    const openDetailsPage = (key) => {
      history.push({
        pathname: 'data',
        search: `?id=${allMetadata[key].DObjectId}&DocTypeCode=${allMetadata[key].DocTypeCode}&DataFormatId=${allMetadata[key].DataFormatId}&OrgIdCreator=${allMetadata[key].OrgIdCreator}&OrgIdHost=${allMetadata[key].OrgIdHost}&TagsContent=${allMetadata[key].TagsContent}&TagsDomain=${allMetadata[key].TagsDomain}&TimestampCreated=${allMetadata[key].TimestampCreated}&TimestampUpdated=${allMetadata[key].TimestampUpdated}`
      });
    };
    

    In Metadata.js, you can use useLocation to access these query parameters:

    import { useLocation } from 'react-router-dom';
    
    const Metadata = (props) => {
      const { search } = useLocation();
      const queryParams = new URLSearchParams(search);
    
      // Access the data using queryParams.get
      const id = queryParams.get('id');
      const docTypeCode = queryParams.get('DocTypeCode');
      const dataFormatId = queryParams.get('DataFormatId');
      const orgIdCreator = queryParams.get('OrgIdCreator');
      const orgIdHost = queryParams.get('OrgIdHost');
      const tagsContent = queryParams.get('TagsContent');
      const tagsDomain = queryParams.get('TagsDomain');
      const timestampCreated = queryParams.get('TimestampCreated');
      const timestampUpdated = queryParams.get('TimestampUpdated');
      // ...
    
      // Now, you can use these variables in your component.
    };
    
  2. Passing Additional Data:

    If you need to pass more data from your parent component (e.g., FindAllMetadata) to AllMetadataTable, you can do this by passing props as you've been doing. You can pass the additional data as props to AllMetadataTable, and then use that data when generating the table.

  3. State Management:

    If you find that your application involves complex state management or data sharing between components, you might also consider using a state management library like Redux or React Context API. This can make it easier to share data between different parts of your application without prop drilling.

Remember to make sure that the data you're trying to access or pass is available and correctly structured in your application.

英文:

I have created react app. I have directory components with folder pages where I have FindAllMetadata component in which I am making GET request and getting all metadata from API. I am passing loadedMetadata to AllMetadataTable as props. AllMetadataTable component is located in other folder called data. There I am displaying some information about fetched metadata items in table ( Creator, Time Created, Format ) and other fetched properties I am not displaying. In a table aside of the every fetched metadata I have + button which when clicked makes link ( route ) to the new page where I want display all information about fetched metadata, single clicked metadata item. Details component is located in folder pages. I want to display clicked Metadata from AllMetadataTable in Details page or in Metadata component.

Here is my App.js :

    import React, { Suspense } from 'react';
    import {  Switch, Route, BrowserRouter } from 'react-router-dom';
    import classes from './App.module.css'
    import LoadingSpinner from './components/UI/LoadingSpinner';
    import Layout from './components/layout/Layout';
    import Footer from './components/layout/Footer';
    import RequestMenu from './components/UI/RequestMenu';


    // load components only when user gets to them
    const Dashboard = React.lazy(() => import('./components/pages/Dashboard'));
    const NewData = React.lazy(() => import('./components/pages/NewData'));
    const NotFound = React.lazy(() => import('./components/pages/NotFound'));
    const FindAllReceivedRequests = React.lazy(() => import('./components/pages/FindAllReceivedRequests'));
    const FindAllGivenConsents = React.lazy(() => import('./components/pages/FindAllGivenConsents'));
    const ReadConsent = React.lazy(() => import('./components/pages/ReadConsent'));
    const FindData = React.lazy(() => import('./components/pages/FindData'));
    const FindAllMetadata = React.lazy(() => import ('./components/pages/FindAllMetadata'));
    const NewPartnerRequest = React.lazy(() => import('./components/pages/NewPartnerRequest'));
    const FindAllGivenRequests = React.lazy(() => import('./components/pages/FindAllGivenRequests'));
    const FindAllReceivedConsents = React.lazy(() => import('./components/pages/FindAllReceivedConsents'));
    const Metadata = React.lazy(() => import('./components/data/Metadata'));


   function App() {
    return (

    <BrowserRouter>
    <Layout>
      <Suspense fallback= { <div className = { classes.centered }> <LoadingSpinner /> </div> } >
        <Switch>

        <Route path ='/' exact>
          <Dashboard />
          <FindData />
        </Route> 

        <Route path= '/new-data' exact>
         <NewData />
        </Route>

        <Route path= '/metadata' exact>
         <FindAllMetadata />
        </Route>

        <Route path = '/data'>
         <Metadata />
          </Route> 

        <Route path= '/request' exact>
          <RequestMenu />
         <FindAllReceivedRequests />
         <section style = {{ marginTop: '5rem',
                            
                            }}>
         <FindAllGivenConsents />
         </section>
        </Route>

        <Route path= '/givenrequest' exact>
          <RequestMenu />
         <FindAllGivenRequests />
         <section style = {{ marginTop: '5rem',
                            
                            }}>
         <FindAllReceivedConsents />
         </section>
        </Route>

        <Route path= '/transfer-data' exact>
         <ReadConsent />
        </Route>

        <Route path= '/partner-request' exact>
         <NewPartnerRequest />
        </Route>

        <Route path= '*'>
          <NotFound />
        </Route>

          </Switch>
         </Suspense>
       </Layout>
       <Footer />
      </BrowserRouter>
     
     );
    }

    export default App;

Here is my FindAllMetadata.js where I am fetching allMetadata ( it is working ):

     import React, {  useState, useEffect, useMemo } from 'react';
     import AllMetadataTable from '../data/AllMetadataTable';
     import LoadingSpinner from '../UI/LoadingSpinner';
     import styles from '../UI/Messages.module.css';
     import styled from '../style/Form.module.css';
     import { readAllMetadata } from '../lib/api';


       const FindAllMetadata = () => {
        const [allMetadata, setAllMetadata] = useState([]);
        const [isLoading, setIsLoading] = useState(false);
        const [error, setError] = useState(null);
        const [enteredMetadataFilter, setEnteredMetadataFilter] = useState('all');
  
         
                 // When page is loaded immediately fetch (and display) all metadata (only running the  effect when                   enteredMetadataFilter changes) 
       useEffect(() => {
        // fetch metadata by entered request filter (all or my) 
     const readAllMetadataHandler = async () => {
        setIsLoading(true);
        setError(null);
      try {
        const loadedAllMetadata = await readAllMetadata(enteredMetadataFilter);
        setAllMetadata(loadedAllMetadata);
      } catch (error) {
        setError(error);
        }
        setIsLoading(false);
      };
    readAllMetadataHandler();
    }, [enteredMetadataFilter]);

    // display fetched content
    const content = useMemo(() => {
    if (error) {
      return <div className={styles.negative}> { error.message } </div>;
    } else if (isLoading) {
      return <section style = {{margin : '1rem 17rem' }} ><LoadingSpinner /> </section>;
    } else {
      return  (
              <AllMetadataTable allMetadata = { allMetadata }
                                metadataFilter = { enteredMetadataFilter }
                                issLoading = { isLoading }
                />
          
        );
       }  
    }, [isLoading, error, allMetadata, enteredMetadataFilter]);

    return  (
        <>
        {/** pick filter for displaying metadata */}
        {!isLoading && 
        <section style= {{ marginLeft : '-10rem'}} >
          <select className={styled.selectControl}
                            onChange={ event => {
                                    setEnteredMetadataFilter(event.target.value);         
                            }} >
                                                                                                                


                       <option value='' disabled style={{ color: '#cccccc' }} > Choose an option      
                     </option>
                            <option value = 'all'> All Metadata </option>
                            <option value = 'my'> My Data </option>
                            </select> 
          
        </section>
        }
    <section>
      {/**display content by status: error, loading, allmetadata, mymetadata */}
        { content }
    </section>
        </>
      )
    }

    export default FindAllMetadata;

Here is my AllMetadataTable.js component where I am displaying fetched metadata in a table ( it is working and when I click + button it is redirecting me to correct URL ) :

    import React from 'react';
import { Table, Button } from 'semantic-ui-react';
import "semantic-ui-css/components/table.min.css";
//import Metadata from './Metadata';
import classes from '../style/Form.module.css';
import Time from '../time/time';
import { useHistory } from 'react-router-dom';
import Metadata from './Metadata';
const AllMetadataTable = ({ allMetadata, metadataFilter, issLoading }) => {
const history = useHistory();
// sorted by time created - newest first
const allMetadataSorted = [...allMetadata].sort((a, b) => {
return new Date(b.TimestampCreated) - new Date(a.TimestampCreated);
});
// open details page for wanted metadata
const openDetailsPage = (key) => {
history.push({
pathname: 'data',
search: `?id=${allMetadata[key].DObjectId}`
})
}; 
return (
<>
{!issLoading &&
<Table celled fixed singleLine
style={{
width : '60rem',
marginLeft: '-10rem',
}} >
<Table.Header>
<Table.Row>
<Table.HeaderCell>Creator</Table.HeaderCell>
<Table.HeaderCell>Host</Table.HeaderCell>
<Table.HeaderCell>Domain</Table.HeaderCell>
<Table.HeaderCell>Format</Table.HeaderCell>
<Table.HeaderCell>Time Created</Table.HeaderCell>
<Table.HeaderCell
style={{
width : '4rem',
}}>Details</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{allMetadataSorted.map((metadata) => (
<React.Fragment key={metadata.key}>
<Table.Row>
<Table.Cell>{metadata.OrgIdCreator}</Table.Cell>
<Table.Cell>{metadata.OrgIdHost}</Table.Cell>
<Table.Cell>{metadata.TagsDomain}</Table.Cell>
<Table.Cell>{metadata.DataFormatId}</Table.Cell>
<Table.Cell>{Time(metadata.TimestampCreated)}</Table.Cell>
<Table.Cell>
{/** open/close metadata */}
<Button className={classes.uichange}
style ={{
border: 'none',
borderRadius: '0px',         
color: 'white', 
cursor: 'pointer', 
backgroundColor: '#19a47c', 
margin: '0 1rem',
fontSize : 22 }}
onClick={() => openDetailsPage(metadata.key) }>
+
</Button>
</Table.Cell>
</Table.Row>
</React.Fragment>
))}
</Table.Body>
</Table>
}
</>
);
};
export default AllMetadataTable;`
Here is my Metadata.js component which I wanna show in a new page when + button in a table is clicked ( id I am getting is corrrect and it is displaying in a list correctly but all other fields are empty; how can I access other fields and display them ?) : 
`import React from 'react';
import classes from '../style/SingleData.module.css';
import list from '../style/List.module.css';
import { Button } from 'semantic-ui-react';
//import styles from '../UI/Messages.module.css';
import LoadingSpinner from '../UI/LoadingSpinner';
import Time from '../time/time';
import { useLocation } from 'react-router-dom';
/** import ORG_NAME  */
const ORG = process.env.REACT_APP_ORG_NAME;
const Metadata = (props) => {
const { search } = useLocation();
const id = new URLSearchParams(search).get('id');
console.log(id);
// close metadata 
const stopReadingDataHandler = () => {
props.onClose()
};
return (
<>
<ul className={list.tableList} >
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>  Data Id:  </strong> {id} 
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong> Doc Type Code: </strong> {props.DocTypeCode}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong> Data Format: </strong> {props.DataFormatId}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>Creator: </strong> {props.OrgIdCreator}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong> Host: </strong> {props.OrgIdHost}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>Tags Content: </strong> {props.TagsContent}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>Domain: </strong> {props.TagsDomain}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>Time Created: </strong> {Time(props.TimestampCreated)}
</li>
<li style={{ borderRadius: '0px' }} className={classes.data}>
<strong>Time Updated: </strong> {Time(props.TimestampUpdated)}
</li>
{ /** display Cancel button if you are Creator or Host */}
{!props.isLoading && (props.OrgIdCreator === ORG || props.OrgIdHost === ORG) &&     props.transferCheckStatus === false ? 
<div style={{ justifyContent: 'flex-start' }} 
className={classes.Form__actions}>
<Button className={classes.uichangedelete}
style ={{
border: 'none',
borderRadius: '3px',         
color: 'white', 
cursor: 'pointer', 
backgroundColor: 'red', 
margin: '10px',
fontSize : 22 }} 
type= 'button'
content='Cancel'
onClick={ stopReadingDataHandler }
/> 
</div>
: null }
{/** display loading spinner if loading */}
{props.isLoading && <LoadingSpinner />}
</ul>
</>
);
};
export default Metadata;

I tried using props inside FindAllMetadata, inside AllMetadataTable; I created other page Details.js in same folder as FindAllMetadata ( pages folder ) ; I tried useHistory, useLocation, useParams etc. `

答案1

得分: 1

在你的openDetailsPage函数中,你只传递了id给Metadata组件:

const openDetailsPage = (key) => {
  history.push({
    pathname: 'data',
    search: `?id=${allMetadata[key].DObjectId}`
  })
};

你使用了history.push方法,参数如下:

  1. pathname => 为Metadata组件设置为'/data'。
  2. search => 用于向URL添加查询参数(注意:这里只传递了id)。

尝试添加以下内容:
3. state => 传递给Metadata组件的对象:

history.push({
  pathname: 'data',
  search: `?id=${allMetadata[key].DObjectId}`,
  state: { item: allMetadata[key] }
});

然后,在Metadata组件中通过以下方式访问它:

props.location.state.item
英文:

In your openDetailsPage function you are passing only the id to the Metadata component:

const openDetailsPage = (key) => {
history.push({
pathname: 'data',
search: ?id=${allMetadata[key].DObjectId}
})
};

You are using history.push method with the following parameters:

  1. pathname => which is '/data/ for Metadata component
  2. search => query to url (NOTE: Here you are passing only the id)
    Try adding:
  3. state => an object to pass to the Metadata components:

history.push({

      pathname: 'data',
search: `?id=${allMetadata[key].DObjectId}`,
state: {item: allMetadata[key]}

})

Then access it on the Metadata component by using:
props.location.state.item

huangapple
  • 本文由 发表于 2023年2月16日 18:40:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定