首页 > 解决方案 > 使用 React Hooks 在两个独立组件之间传递状态的问题

问题描述

所以我的问题是,我基本上是在尝试传递从主页上的 API 获取的数据,这些数据在按下提交按钮时被获取并存储在“geo”变量中,并将其传递到地图页面(通过在提交邮政编码后按地图按钮访问),然后它将使用“geo”(geo.result.latitude/longitude)中的纬度和经度在加载时从另一个 API 获取并在页面上显示该数据. 但是,我在理解如何使用钩子在两个组件/页面(主页和地图)之间传递状态(或地理变量中的值)时遇到问题。我对 React 相当陌生,对 Hooks 也很陌生,所以目前我的理解非常基础。任何帮助将非常感激 :)

主页.js

import React, { useState, useEffect, useCallback } from 'react'
import { Link } from 'react-router-dom'

const Home = () => {

  const [postCode, setPostcode] = useState({

    pCode: ''

  })

  const [geo, setGeo] = useState([])

  const fetchRequest = useCallback((e) => {
    e.preventDefault()
    fetch(`https://api.postcodes.io/postcodes/${postCode.pCode}`)

      .then(res => res.json())
      .then(res => setGeo(res))

    console.log(geo)

  }, [{ ...postCode }])

  const handleChange = (e) => {
    setPostcode({ ...postCode, pCode: e.target.value })
    console.log(postCode)

  }

  return <section >

    <div className='container'>

      <form className="form" onSubmit={fetchRequest}>
        <input className="input" type="text" placeholder="Text input" onChange={handleChange} />
        < button>submit</button>
        <Link className='button' to={{
          pathname: '/maps'
        }}>Map

        </Link>
      </form>

    </div>

  </section>

}

export default Home

Maps.js

const Maps = () => {

  const [events, setEvents] = useState([])

  const fetchRequest = useCallback(() => {

    fetch(`https://api.list.co.uk/v1/events?near=${viewport.latitude},${viewport.longitude}/10`, {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    })
      .then(res => res.json())
      .then(res => setEvents(res))


  }, [{ ...viewport }])

  useEffect(() => {

    fetch(`https://api.list.co.uk/v1/events?near=${geo.result.latitude},${geo.result.longitude}/10`, {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    })
      .then(res => res.json())
      .then(res => setEvents(res))

    return () => console.log('Unmounting component')

  }, [])

  const [viewport, setViewport] = useState({
    width: '100vw',
    height: '100vh',
    latitude: 51.45523,
    longitude: -2.59665,
    zoom: 13.5

  })

  if (events.length === 0) {
    return <div>Loading...</div>
  }

  return <div>
    <ReactMapGL mapboxApiAccessToken={TOKEN}
      mapStyle="mapbox://styles/dredizzle/ck3owxclr138a1cqnzupab2hc"
      {...viewport}
      onViewportChange={viewport => {
        setViewport(viewport)
      }}
      onClick={
        fetchRequest
      }

    >

      {events.map(event => (
        <Popup
          key={event.event_id}
          latitude={event.schedules[0].place.lat}
          longitude={event.schedules[0].place.lng}
        >
        </Popup>
      ))}


      {/* <Popup latitude={51.45523} longitude={-2.59665}>
        <div>event here</div>
      </Popup> */}
      <GeolocateControl
        positionOptions={{ enableHighAccuracy: true }}
        trackUserLocation={false}
      />
    </ReactMapGL>
  </div>
}

export default Maps

标签: javascriptreactjsstatereact-hookssetstate

解决方案


在 Maps 组件中,我认为您正在覆盖events重复此行时的值:

const [events, setEvents] = useState([])

您应该只能this.state.events在 Maps 组件内引用,并在 Maps 内使用从组件内向数组this.setState()添加数据。events


推荐阅读