react.js中的函数需要运行两次才能工作



我正在用Firestore做React项目。使用API结果,我希望用户能够将其中一些作为收藏夹。这是可行的,但是当您首先单击时,handleFavorite()和saveFavorite()将为每个字段返回一个空字符串。第二次,所有值都是正确的。

export default function MostPopular() {
const [mostPopulars, setMostPopulars] = useState([])
const { currentUser } = useAuth()
const [author, setAuthor] = useState('')
const [date, setDate] = useState('')
const [description, setDescription] = useState('')
const [section, setSection] = useState('')
const [title, setTitle] = useState('')
const [url, setUrl] = useState('')
const [user, setUser] = useState('')
/* firestore collection */
const favoritesCollectionRef = collection(db, 'favorites')
/* console.log(favoritesCollectionRef) */
function handleFavorite(post) {
setUser(currentUser.uid)
setAuthor(post.byline)
setDate(post.published_date)
setDescription(post.abstract)
setSection(post.section)
setTitle(post.title)
setUrl(post.url)
setUser(currentUser.uid)
console.log({ author, date, description, section, title, url, user })
}
const saveFavorite = async (post) => {
setAuthor(post.byline)
setDate(post.published_date)
setDescription(post.abstract)
setSection(post.section)
setTitle(post.title)
setUrl(post.url)
setUser(currentUser.uid)
try {
await addDoc(favoritesCollectionRef, {
author,
date,
description,
section,
title,
url,
user,
})
console.log('favorite added')
} catch (err) {
console.log(err)
}
}
useEffect(() => {
/* most popular */
axios
.get(nytMostPopularUrl)
.then((response) => {
/* console.log(response.data.results) */
setMostPopulars(response.data.results)
})
.catch((err) => {
console.log(err)
setMostPopulars(data)
})
}, [])
return (
<div className='most-populars'>
{mostPopulars.map((post, index) => (
<Card
className='most-populars__card  card bg-dark text-light border-light'
key={index}
>
<span onClick={() => handleFavorite(post)}>handleFavorite here</span>
<span onClick={() => saveFavorite(post)}>save favorite here</span>
<Card.Body>
{' '}
<div className='title-card'>{post.title}</div>
<div className='subtitle'>{post.abstract}</div>
<Card.Text className='author-date'>
<span>{post.byline}</span>{' '}
<span>
Published: {moment(post.published_date).format('MMMM d, YYYY')}
</span>
</Card.Text>
<Button className='btn read-more' variant='btn btn-outline-light'>
<a href={post.url} className='link'>
read more
</a>
</Button>
</Card.Body>
<Card.Footer>
<SharingButtons url={post.url} />
</Card.Footer>
</Card>
))}
</div>
)
}

异步问题,也许?

你的代码一切都很好,问题只是你不能期望在状态更新后立即访问新的状态,因为你是从闭包访问状态,它只在元素呈现后重新创建。如果您想使用console.log检查状态,则需要将console.log移到处理函数之外的组件主体中,这样您将在每个呈现上获得日志。

例如:

function handleFavorite(post) {
setUser(currentUser.uid)
setAuthor(post.byline)
setDate(post.published_date)
setDescription(post.abstract)
setSection(post.section)
setTitle(post.title)
setUrl(post.url)
setUser(currentUser.uid)
}
console.log({ author, date, description, section, title, url, user }); // MOVE HERE
const saveFavorite = async (post) => {
setAuthor(post.byline)
setDate(post.published_date)
setDescription(post.abstract)
setSection(post.section)
setTitle(post.title)
setUrl(post.url)
setUser(currentUser.uid)
try {
await addDoc(favoritesCollectionRef, {
author,
date,
description,
section,
title,
url,
user,
})
console.log('favorite added')
} catch (err) {
console.log(err)
}

}

问题修复。为每个组件使用类组件。初始状态是我需要的每一个值。到目前为止,这是可行的。关闭此问题。

相关内容

最新更新