【问题标题】:How can I simply pass data from a component one page to a component on another page in React/Next.js?在 React/Next.js 中,如何简单地将数据从一个页面的组件传递到另一个页面上的组件?
【发布时间】:2021-12-30 11:45:39
【问题描述】:

总结

我有一个简单的 next.js 应用程序,它有两个页面,index.js 和 results.js。索引页面有两个位置自动完成字段,在用户从推荐位置的下拉列表中选择位置后,它们会返回位置的地址和 LatLng。返回后,此数据将存储在索引页面上名为 markers 的变量中。当用户单击索引页面上的 Get Results 按钮时,我正在尝试将地址和 LatLng 数据传递到结果页面,以便可以将所选位置显示为地图上的标记.

问题

我已经断断续续地尝试了大约一个星期,但我不知道如何实现我想要的。我觉得应该有一个超级简单的方法来做到这一点,但我就是想不通。我试过这样的事情:

  • 在单击按钮时通过请求参数传递数据,但链接是在页面呈现时根据变量值生成的,而不是在变量更新时更新
  • 将地图与位置自动完成功能放在同一页面上并尝试使用状态自动重新加载地图,这对我来说似乎根本不起作用
  • 我也研究过 Redux,但这似乎太复杂了,无法简单地将对象/它的数据从一个页面传递到另一个页面

我理想的解决方案是将数据从 indext 传递到结果的简单方法。可能还值得指出的是,我是 React/Next.js 的新手,所以我可能会以错误的方式处理所有这些问题,一旦这工作正常,我还将添加一个 API 调用以获取两个 LatLng 点也将显示在结果页面的地图上。

代码

index.js(简体)

{/* Import used next and style objects */ }
import Head from 'next/head'
import styles from '../styles/Home.module.css'

{/* Import react-bootstrap */ }
import { Container, Row, Col } from 'react-bootstrap'

{/* Import geosuggest */ }
import Geosuggest from 'react-geosuggest'

{/* Import used components */ }
import NavigationBar from '../components/NavigationBar'
import Footer from '../components/Footer'

{/* Import and use runtime vars for Google API */ }
import getConfig from "next/config"
const { publicRuntimeConfig } = getConfig()
const GoogleApiUrl = `https://maps.googleapis.com/maps/api/js?key=${publicRuntimeConfig.MAPS_JAVASCRIPT_API_KEY}&libraries=places`

export default function Home() {

  const markers = {
    from: {description: "", lat: 0, lng: 0},
    to: {description: "", lat: 0, lng: 0}
  }

  const onFromSuggestSelect = (suggest) => {
    console.log("New FROM location selected: \"" + suggest.description + "\"");
    markers.from.description = suggest.description
    markers.from.lat = suggest.location.lat
    markers.from.lng = suggest.location.lng
  }

  const onToSuggestSelect = (suggest) => {
    console.log("New TO location selected: \"" + suggest.description + "\"");
    markers.to.description = suggest.description
    markers.to.lat = suggest.location.lat
    markers.to.lng = suggest.location.lng
  }

  return (
    <div>
      <Head>
        <title>MyApp</title>
        <meta name="description" content="MyApp" />
        <link rel="icon" href="/favicon.ico" />
        <script src={GoogleApiUrl}></script>
      </Head>

      <NavigationBar/>

      <div className={styles.container}>
        <main>
          <Container>
            <Row className="text-center">
              <Col md={1}></Col>
              <Col md={5}><Geosuggest data-test-id="autocomplete-start-test" placeholder="From..." onSuggestSelect={onFromSuggestSelect} country="gb"  minLength="3" /></Col>
              <Col md={5}><Geosuggest data-test-id="autocomplete-end-test" placeholder="To..." onSuggestSelect={onToSuggestSelect} country="gb"  minLength="3" /></Col>
              <Col md={1}></Col>
            </Row>
          </Container>
        </main>

        <Footer/>

      </div>
    </div>
  )
}

results.js(简体)

{/* Import used next and style objects */ }
import Head from 'next/head'
import styles from '../styles/Home.module.css'

{/* Import used react-bootstrap objects */ }
import { Container } from 'react-bootstrap'

{/* Import used components */ }
import NavigationBar from '../components/NavigationBar'
import Footer from '../components/Footer'
import Map from '../components/Map'

{/* Import and use runtime vars for Google API */ }
import getConfig from "next/config"
const { publicRuntimeConfig } = getConfig()
const GoogleApiUrl = `https://maps.googleapis.com/maps/api/js?key=${publicRuntimeConfig.MAPS_JAVASCRIPT_API_KEY}&libraries=places`

export default function Home() {

    const markers = {
        from: {description: "", lat: 0, lng: 0},
        to: {description: "", lat: 0, lng: 0}
      }

  return (
    <div>
      <Head>
        <title>MyApp</title>
        <meta name="description" content="MyApp" />
        <link rel="icon" href="/favicon.ico" />
        <script src={GoogleApiUrl}></script>
      </Head>

      <NavigationBar/>

      <div className={styles.container}>
        <main>
            <Container>
                {/* MARKERS NEEDS TO BE PASSED IN ON THE LINE BELOW */}
                <Map markers={markers}/> 
            </Container>
        </main>
      </div>
      
      <Footer/>

    </div>
  )
}

Map.js(组件)

import React from "react"
import { GoogleMap, Marker } from "@react-google-maps/api"

export default class Map extends React.Component {
    render() {
        // Set the map to fill its container
        const containerStyle = { width: '500px', height: '500px' }
          
        // Set the map to show the entire UK on initial load
        const center = { lat: 54.476422, lng: -3.397340 }
        const zoom = 6

        // Return the map with the above defaults
        return(
            <GoogleMap mapContainerStyle={containerStyle} center={center} zoom={zoom}>
                <Marker position={{ lat: this.props.markers.from.lat, lng: this.props.markers.from.lng }} />
                <Marker position={{ lat: this.props.markers.to.lat, lng: this.props.markers.to.lng }} />
            </GoogleMap>
        )
    }
}

【问题讨论】:

    标签: javascript reactjs next.js react-google-maps


    【解决方案1】:

    我认为这里有两个问题:

    1. 如何在两个 NextJS 页面之间传递数据?
    2. suggest 值更新时,为什么我的链接没有更新?

    有几种不同的方法可以在页面之间传递数据,但查询字符串参数可能是我会使用的方法。尽管如果可能的话,我不会使用查询字符串中的描述。您可以使用NextJS &lt;Link /&gt; component

    但是,您似乎已经尝试过类似的操作,并且链接没有更新。原因是markers 数据的设置方式。您已在组件中将其设置为 const,这告诉 React 不要监视对此对象的更改。当onFromSuggestSelect 触发时,它会更新对象属性,然后……什么都没有。 React 认为 &lt;Link /&gt; 不会有任何变化,因为 Parent 没有任何变化。

    这就是我们有 React State 的原因。如果您将markers const 更改为使用useState 挂钩,您应该会发现实现的&lt;link /&gt; 将在值更改时更新。

    一句警告;如果您之前没有使用过 useState 钩子,请仔细阅读文档,以便了解如何正确实现。

    我希望这能解决你的问题。

    【讨论】:

    • 谢谢 Stuart - 您的建议很明确,文档链接非常有用。你现在让我免于到处乱跑!数据现在被传递到第二页,对我来说下一步是从查询参数中获取它,这应该很容易。
    猜你喜欢
    • 2017-01-25
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多