首页 > 解决方案 > 如何渲染一组 JSX 片段?

问题描述

我对 React 比较陌生,并试图渲染一组看起来像这样的 JSX 片段。

                       <>
                        <div className="tourCard" key={address.name}>
                          <h3 className="tourCard__header">{address.name}</h3>
                          <div className="tourCard__capacity">Capacity: {foundUser.capacity}</div>
                          {foundUserAddress}
                          {foundUserAddress2}
                          <section className="tourCard__cityStateZip">
                            <div className="tourCard__city">{foundUser.city}</div>
                            <div className="tourCard__state">{foundUser.state}</div>
                            {foundUserZip}
                          </section>
                          <h5 className="tourCard__blurbHeader">About Us</h5>
                          {foundUserBlurb}
                          {socialMediaButtonClicked ? (
                            <>
                            {foundUserSocialMedia}
                            </>
                          ) : (
                            <>
                            <button onClick={() => {
                              socialMediaButtonClicked = true
                            }}>Social media</button>
                            </>
                          )}
                        </div>
                    </>

我正在将它们完全像上面一样推入一个数组,并且我在下面的 return 语句中努力使用正确的格式来让它们呈现。

我试过了

return (
      <>
        <section className="tourSection">
          {tourCards}
        </section>
        </>
    )

return (
      <>
        <section className="tourSection">
          {tourcards.map(tourCard => {
            return(
              {tourCard}
            )
          }
        </section>
        </>
    )

但两者都没有成功。我哪里错了?

完整的页面代码如下:

import React, {useContext, useState} from "react"
import { withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps'
import { AddressContext } from "../addresses/AddressProvider"
import { UserContext } from "../user/UserProvider"
import { render } from '@testing-library/react'

export default (props) => {

  const { addresses } = useContext(AddressContext)
  const { users } = useContext(UserContext)

  let tourCards = []

  const PlanMap = withGoogleMap(props => (
    <GoogleMap google={window.google} defaultCenter = { { lat: 39.5, lng:  -98.35 } }
    defaultZoom = { 4 }>
          {
            addresses.map(address => 
              <>
              <Marker
                key={address.id}
                position={{
                  lat: address.address.lat,
                  lng: address.address.lng
                }}
                label={{
                  text: "Hello World!",
                  fontFamily: "Arial",
                  fontSize: "14px",
                }}
              >
                <InfoWindow
                  key={address.id}>
                    <>
                  <span>{address.name}</span>
                  <div>
                    <button onClick={() => {
                      let foundUser = users.find(user => user.name === address.name)
                      let foundUserAddress = ""
                      if (foundUser.hasOwnProperty("address") && foundUser.hasOwnProperty("addressPublic") && foundUser.addressPublic === true) {
                        foundUserAddress = <>
                        <div className="tourCard__address">{foundUser.address}</div>
                        </>
                      }
                      let foundUserAddress2 = ""
                      if (foundUser.hasOwnProperty("address2") && foundUser.hasOwnProperty("address2Public") && foundUser.address2Public === true) {
                        foundUserAddress2 = <>
                        <div className="tourCard__address2">{foundUser.address2}</div>
                        </>
                      }
                      let foundUserZip = ""
                      if (foundUser.hasOwnProperty("zip") && foundUser.hasOwnProperty("zipPublic") && foundUser.zipPublic === true) {
                        foundUserZip = <>
                        <div className="tourCard__zip">{foundUser.zip}</div>
                        </>
                      }
                      let foundUserBlurb = ""
                      if (foundUser.hasOwnProperty("blurb") && foundUser.hasOwnProperty("blurbPublic") && foundUser.blurbPublic === true) {
                        foundUserBlurb = <>
                        <div className="tourCard__blurb">{foundUser.blurb}</div>
                        </>
                      }
                      let socialMediaButtonClicked = false
                      let foundUserWebsite = ""
                      let foundUserFacebook = ""
                      let foundUserInstagram = ""
                      let foundUserTwitter = ""
                      let foundUserSocialMedia = <>
                      <section className>
                        {foundUserWebsite}
                        {foundUserFacebook}
                        {foundUserInstagram}
                        {foundUserTwitter}
                      </section>
                      </>
                      if (foundUser.webPublic === true) {
                        if (foundUser.hasOwnProperty("website")) {
                          foundUserWebsite = <>
                          <div className="tourCard__website">{foundUser.website}</div>
                          </>
                        }
                        if (foundUser.hasOwnProperty("facebook")) {
                          foundUserFacebook = <>
                          <div className="tourCard__facebook">{foundUser.facebook}</div>
                          </>
                        }
                        if (foundUser.hasOwnProperty("instagram")) {
                          foundUserInstagram = <>
                          <div className="tourCard__instagram">{foundUser.instagram}</div>
                          </>
                        }
                        if (foundUser.hasOwnProperty("twitter")) {
                          foundUserInstagram = <>
                          <div className="tourCard__twitter">{foundUser.twitter}</div>
                          </>
                        }
                      }
                      tourCards.push(
                        <div className="tourCard" key={address.name}>
                          <h3 className="tourCard__header">{address.name}</h3>
                          <div className="tourCard__capacity">Capacity: {foundUser.capacity}</div>
                          {foundUserAddress}
                          {foundUserAddress2}
                          <section className="tourCard__cityStateZip">
                            <div className="tourCard__city">{foundUser.city}</div>
                            <div className="tourCard__state">{foundUser.state}</div>
                            {foundUserZip}
                          </section>
                          <h5 className="tourCard__blurbHeader">About Us</h5>
                          {foundUserBlurb}
                          {socialMediaButtonClicked ? (
                            <>
                            {foundUserSocialMedia}
                            </>
                          ) : (
                            <>
                            <button onClick={() => {
                              socialMediaButtonClicked = true
                            }}>Social media</button>
                            </>
                          )}
                        </div>
                  )
                  console.log(tourCards)
                  debugger
                    }}
                    >
                      Add to tour
                    </button>
                  </div>
                  </>
                </InfoWindow>
              </Marker>
              </>
            )
          }
          </GoogleMap>
  ));

    return (
      <>
        <div>
          <PlanMap
          loadingElement={<div style={{ height: `100%` }} />}
          containerElement={<div style={{ height: `400px`, width: `400px` }} />}
          mapElement={<div style={{ height: `100%` }} />}
          />
        </div>
        <section className="tourSection">
          {tourCards}
        </section>

        </>
    )

}

标签: reactjsjsx

解决方案


正如我在评论中所说,我认为您的问题只是更新 tourCards 后您的组件没有重新渲染。更重要的是,由于每次您的组件重新渲染时,tourCards 都被重新定义为一个空数组,因此它不会包含您尝试放入其中的任何内容。所以你应该使用useState它来跟踪它。

使用 react hooks 处理数组时,最好将它们视为不可变的,并在每次使用数组扩展设置状态时创建一个新数组

const [arr, setArr] = useState([])
// somewhere in an effect or callback
setArr(prevArr => [...prevArr, newValue]) // this is the same as arr.push
setArr(prevArr => [newValue, ...prevArr]) // this is the same as arr.unshift
setArr(prevArr => [...newArr, ...prevArr]) // this is arr.concat

这是一个工作示例,您应该可以在 SO 上运行:

const {useState} = React

function App() {
  const [tourcards, setTourcards] = useState([])
  const addTourCard = function() {
    // Do whatever you need to do here
    const card = <div key={`card-${tourcards.length}`}>Card</div>
    setTourcards(cards => [...cards, card])
  }
  return (
    <div> 
      <button onClick={addTourCard}>Click Me</button>
      <div>{tourcards}</div>
    </div>
  )
}

ReactDOM.render(<App />, document.querySelector("#root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>


推荐阅读