Я застрял на несколько часов сейчас .. Я пытаюсь отправить компоненту новые реквизиты ... но он не получит новые.
Вот что происходит.
Сначала пользователь нажимает кнопку на компоненте публикации ... Он запускает функции «добавить избранное» и «addFavs» в родительском компоненте ниже. Эти две функции определяют, следует ли добавить пользователя в избранное или удалить пользователя из избранного.
Когда пользователь добавляется в избранное, кнопка, которую он щелкнул внутри компонента searchResults, отображается другим цветом. Проблема в том, что они должны дважды щелкнуть кнопку, чтобы новые реквизиты были отправлены обратно в компонент searchResults, и изменить цвет - и я не могу понять, как получить useEffect для отправки компоненту новых реквизитов.
Внутри функции 'addFavs' я вызываю функции оригинального поиска 'getBands' и 'getTourBands', чтобы получить обновленные данные. Это добавляется к состояниям, называемым полосами, всеми полосами и турами. Моя теория заключалась в том, что как только эти обновленные данные будут добавлены в состояние, они отправят новые реквизиты моему searchResultsComponent.
Спасибо за вашу помощь - дайте мне знать, если это слишком сложно.
import React, { useState, useEffect } from 'react'
import { Button, Card, CardTitle } from 'reactstrap'
import LocationInput from './LocationInput'
import TypeInput from './TypeInput'
import VideosInput from './VideosInput'
import ShowsInput from './ShowsInput'
import VideoPosts from '../../SetupCards/Posts/Views/VideoPosts'
import ShowsPosts from '../../SetupCards/Posts/Views/ShowsPosts'
import FeedPosts from '../../SetupCards/Posts/Views/FeedPosts'
import { useAuth0 } from "../../../react-auth0-spa";
import BandCard from '../../BookABand/BandCard'
import SearchResults from './SearchResults'
let shouldUpdate = 0
export default function BandSearchBar(props) {
const [ isSelected, setIsSelected ] = useState('location')
const [ bands, setBands ] = useState([])
const [ tourBands, setTourBands ] = useState([])
const [ allBands, setAllBands ] = useState([])
const [ locationText, setLocationText ] = useState('')
const [ location, setLocation ] = useState([])
const [ genre, setGenre ] = useState('Genre/Style')
const [ bandTypes, setBandTypes ] = useState('all')
const [ videosFilter, setVideosFilter ] = useState('all')
const [ showsFiltered, setShowsFiltered ] = useState('all')
const { getTokenSilently } = useAuth0();
const { loading, user } = useAuth0();
const getHomeBands = async () => {
const token = await getTokenSilently();
try {
const response = await fetch(`/api/autoquotegenerators/homeBands/${location[0]}/${location[1]}`, {
headers: {
Authorization: `Bearer ${token}`,
}
})
const responseData = await response.json();
if(responseData !== []){
setBands(responseData)
}
} catch (error) {
console.log(error)
}
}
const getTourBands = async () => {
const token = await getTokenSilently();
try {
const response = await fetch(`/api/autoquotegenerators/tourBands/${location[0]}/${location[1]}`, {
headers: {
Authorization: `Bearer ${token}`,
}
})
const responseData = await response.json();
if(responseData !== []){
setTourBands(responseData)
}
} catch (error) {
console.log(error)
}
let allBandsArray = Array.from(bands).concat(tourBands)
setAllBands(allBandsArray)
}
useEffect(() => {
setTimeout(() => {
if(shouldUpdate >= 1){
getHomeBands()
getTourBands()
}else {
shouldUpdate += 1
}
},250)
}, [location])
const searchLocation = (location, text) => {
setLocation(location)
setLocationText(text)
}
const showCard = (set) => {
switch(set){
case 'location':
return <div><LocationInput savedLocationText={locationText} searchLocation={searchLocation} savedGenre={genre} filterByGenre={filterByGenre} /></div>
case 'bands':
return <div><TypeInput savedType={bandTypes} filterBandTypes={filterBandTypes} /> </div>
case 'videos':
return <div><VideosInput filterByVideos={filterByVideos} videosFilter={videosFilter} /> </div>
case 'shows':
return <div><ShowsInput filterShows={filterShows} showsFiltered={showsFiltered}/> </div>
}
}
if (loading || !user) {
return <div>Loading...</div>;
}
const addRockOn = async (postId, rocks, _id) => {
const token = await getTokenSilently();
try {
await fetch(`/api/autoquotegenerators/posts/${_id}/${postId}`,{
method: 'PUT',
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify({
rockOn: rocks
})
})
} catch (error) {
console.log(error)
}
}
const addFavorites = (userId, band) => {
if(band.favorites.includes(userId)){
addFavs(band.favorites.filter(fav => {
return fav !== userId
}), band._id)
}else {
addFavs(band.favorites.concat(userId), band._id)
}
}
const addFavs = async (favs, id) => {
const token = await getTokenSilently();
try{
await fetch(`/api/autoquotegenerators/${id}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify({
favorites: favs
})
})
getHomeBands()
getTourBands()
} catch(error){
console.log(error)
}
}
const convertPost = (post, band) => {
if(genre === 'Genre/Style'){
switch (post.type) {
case "video":
return (
<VideoPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} link={post.data} band={band} post={post} _id={band._id} />
)
case "text":
return (
<FeedPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
)
case "show":
return (
<ShowsPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
)
default:
return null;
}
}else {
if(band.bandGenre === genre ){
switch (post.type) {
case "video":
return (
<VideoPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} link={post.data} band={band} post={post} />
)
case "text":
return (
<FeedPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id} />
)
case "show":
return (
<ShowsPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
)
default:
return null;
}
}
}
}
const convertBand = (band) => {
if(genre === 'Genre/Style'){
return <Button color="light" className="w-100 mb-1">
<BandCard id={band._id} key={band.bandName} youtube={band.youtube} bandName={band.bandName} bandBio={band.bandBio} />
</Button>
}else {
if(band.bandGenre === genre){
return <Button color="light" className="w-100 mb-1">
<BandCard id={band._id} key={band.bandName} youtube={band.youtube} bandName={band.bandName} bandBio={band.bandBio} />
</Button>
}
}
}
const createPromoVideo = (link, band) => {
let post = {
date: null
}
return <VideoPosts post={post} link={link} band={band} _id={band._id} />
}
const filterBandTypes = (type) => {
setBandTypes(type)
}
const filterByGenre = (genre) => {
setGenre(genre)
}
const filterByVideos = (videos) => {
setVideosFilter(videos)
}
const filterShows = (shows) => {
setShowsFiltered(shows)
}
return (
<div className="d-flex flex-column">
<div className="d-flex flex-row">
<Button id="location" onClick={() => {setIsSelected('location')}}
color={isSelected === 'location' ? "dark active" : "dark"} className="w-100 h5" style={{borderTopLeftRadius: '3px', borderBottomLeftRadius: '3px', borderTopRightRadius: '0px', borderBottomRightRadius: '0px'}} >Feed</Button>
<Button id="bands" onClick={() => {setIsSelected('bands')}} color={isSelected === 'bands' ? "dark active" : "dark"} className="w-100 h5 rounded-0">Bands</Button>
<Button id="videos" onClick={() => {setIsSelected('videos')}}
color={isSelected === 'videos' ? "dark active" : "dark"} className="w-100 h5 rounded-0">Videos</Button>
<Button id="shows" onClick={() => {setIsSelected('shows')}} color={isSelected === 'shows' ? "dark active" : "dark"} className="w-100 h5" style={{borderTopRightRadius: '3px', borderBottomRightRadius: '3px', borderTopLeftRadius: '0px', borderBottomLeftRadius: '0px'}}>Shows</Button>
</div>
<div>
{isSelected ? showCard(isSelected) : null}
</div>
<SearchResults isSelected={isSelected} bandTypes={bandTypes} allBands={allBands} bands={bands} tourBands={tourBands} convertPost={convertPost} convertBand={convertBand} videosFilter={videosFilter} showsFiltered={showsFiltered} createPromoVideo={createPromoVideo}/>
</div>
)
}
Я также пытался использовать хук useEffect () для вызова функции для отображения компонента с новыми реквизитами. Еще ничего. ** Когда я попробовал использовать эффект, я прослушал «группы», «allBands» и «tourBands». Если бы они изменились, он передал бы компонент в функцию, которая отображала бы его в рендере - это не сработало, поэтому я не включил его в мой код выше.
Вот файл / компонент SearchRestuls. js
import React from 'react'
export default function SearchResults(props) {
const {isSelected, bandTypes, allBands, bands, tourBands, convertPost, convertBand, videosFilter, showsFiltered, createPromoVideo} = props
return (
<div>
<div style={{
display: isSelected === 'location' ? 'block' : 'none'
}}>
{bandTypes === 'all' ? allBands.map(band => {
return band.posts.map(post => {
let currPost = convertPost(post, band)
return currPost
})
}).reverse() : null}
{bandTypes === 'local' ? bands.map(band => {
return band.posts.map(post => {
let currPost = convertPost(post, band)
return currPost
})
}).reverse() : null}
{bandTypes === 'touring' ? tourBands.map(band => {
return band.posts.map(post => {
let currPost = convertPost(post, band)
return currPost
})
}).reverse() : null}
</div>
<div style={{
display: isSelected === 'bands' ? 'block' : 'none'
}}>
{bandTypes === 'all' ? allBands.map(band => {
let currBand = convertBand(band)
return currBand
}) : null}
{bandTypes === 'local' ? bands.map(band => {
let currBand = convertBand(band)
return currBand
}) : null}
{bandTypes === 'touring' ? tourBands.map(band => {
let currBand = convertBand(band)
return currBand
}) : null}
</div>
<div style={{
display: isSelected === 'videos' ? 'block' : 'none'
}}>
{bandTypes === 'all' && videosFilter === 'all' ? allBands.map((band) => {
return band.posts.map(post => {
if(post.type === 'video'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'local' && videosFilter === 'all' ? bands.map((band) => {
return band.posts.map(post => {
if(post.type === 'video'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'touring' && videosFilter === 'all' ? tourBands.map((band) => {
return band.posts.map(post => {
if(post.type === 'video'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'all' && videosFilter === 'promo' ? allBands.map((band) => {
return band.youtube.map(link => {
let currVid = createPromoVideo(link, band)
return currVid
})
}) : null}
</div>
<div style={{
display: isSelected === 'shows' ? 'block' : 'none'
}}>
{bandTypes === 'all' && showsFiltered === 'all' ? allBands.map((band) => {
return band.posts.map(post => {
if(post.type === 'show'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'local' && showsFiltered === 'all' ? bands.map((band) => {
return band.posts.map(post => {
if(post.type === 'show'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'touring' && showsFiltered === 'all' ? tourBands.map((band) => {
return band.posts.map(post => {
if(post.type === 'show'){
let currBand = convertPost(post, band)
return currBand
}
})
}) : null}
{bandTypes === 'all' && showsFiltered === 'upcoming' ? allBands.map((band) => {
return band.posts.map(post => {
if(post.type === 'show'){
let performanceDateUnformatted;
performanceDateUnformatted = post.details.filter(detail => {
if(detail.title === 'Performance Date'){
return detail.detail
}
})[0].detail
var months = {
'Jan' : '01',
'Feb' : '02',
'Mar' : '03',
'Apr' : '04',
'May' : '05',
'Jun' : '06',
'Jul' : '07',
'Aug' : '08',
'Sep' : '09',
'Oct' : '10',
'Nov' : '11',
'Dec' : '12'
}
let year = performanceDateUnformatted.slice(11)
let day = performanceDateUnformatted.slice(8,10)
let month = months[performanceDateUnformatted.slice(4,7)]
let showDateFormatted = new Date(year, month - 1, day)
let today = new Date()
let todayPlusOneWeek = new Date(today.getUTCFullYear(), today.getUTCMonth(), today.getDate() + 7)
if(showDateFormatted > today && showDateFormatted < todayPlusOneWeek ){
let currBand = convertPost(post, band)
return currBand
}else {
return null
}
}
})
}) : null}
</div>
</div>
)
}