reactjs - 如何渲染一组 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>
</>
)
}
解决方案
正如我在评论中所说,我认为您的问题只是更新 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>
推荐阅读
- css - 如何使图钉跟随地图?
- javascript - 此代码在 chrome 控制台中返回意外的标识符。但此函数仍然有效并返回答案。我出错了吗?
- java - 是否可以在 java/swing 中的屏幕程序上编写绘画?
- .net - 如何区分 .NET 中的空字符串和零长度字符串?
- facebook - Facebook 区域设置和货币
- drag-and-drop - 在 TListView 和旧版本的 C++ Builder 上闪烁
- laravel - Laravel API,如何接受 DELETE 方法
- python - Python Selenium - 根据字符串查找表格元素并单击关联单选按钮
- ios - 使用 Alamofire 获取响应
- javascript - 表单不会提交并给出错误信息