Tyc*_*liz 8 reactjs react-hooks
Previous render Next render
------------------------------------------------------
1. useState useState
2. useContext useContext
3. useEffect useEffect
4. undefined useState
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in ExperienceDetailContainer (created by ConnectFunction)
in ConnectFunction (created by Route)
in Route (created by withRouter(Connect(ExperienceDetailContainer)))
in withRouter(Connect(ExperienceDetailContainer)) (created by ExperiencePage)
Run Code Online (Sandbox Code Playgroud)
使用钩子在这里出现意外错误。根据我的理解,只要以可预测的顺序调用钩子,一切都应该正常工作。查看我的组件告诉我就是这种情况,我无法理解错误的来源。
import React, { useState, useEffect } from 'react'
import { withRouter } from 'react-router-dom'
import T from 'prop-types'
import { useWait } from 'react-wait'
import { connect } from 'react-redux'
import api from 'services/api'
import {
formattedDateWithoutTime,
getTimesForCurrentDate
} from 'utils/helpers'
import { fromResource, fromUserSelections, fromSocial } from 'store/selectors'
import {
resourceDetailReadRequest,
changeExperienceDate,
changeExperienceTime,
updateExperience,
} from 'store/actions'
import { ExperienceDetail, Spinner } from 'components'
const ExperienceDetailContainer = ({
detail,
readDetail,
experienceDate,
changeExperienceDate,
experienceTime,
changeExperienceTime,
adults,
kids,
updateExperience,
user,
...props
}) => {
const [error, setError] = useState('')
const { startWaiting, endWaiting } = useWait()
useEffect(() => {
readDetail(apiRequestParams)
getExperienceAvailabilities()
}, [])
const experienceId = props.match.params.experienceid
const cityId = props.match.params.cityid
const apiRequestParams = {
endpoint: "GetExperienceInfo",
experienceid: experienceId,
adults,
kids
}
const availableStartTimes = getTimesForCurrentDate(experienceDate, detail.availabilities)
const getExperienceAvailabilities = () => {
api.post('/GetExperienceAvailabilities', {
experienceid: experienceId
})
.then(result => {
const availabilities = result.d
updateExperience(availabilities)
})
.catch(err => {
console.error(err)
})
}
if (!detail.experienceid) {
return <Spinner />
}
return <ExperienceDetail
loading={!detail.experienceid}
{...{
detail,
error,
experienceId,
availableStartTimes,
changeExperienceDate,
experienceDate,
changeExperienceTime,
experienceTime,
getQuoteBooking,
}}/>
}
ExperienceDetailContainer.propTypes = {
detail: T.object.isRequired,
changeExperienceDate: T.func.isRequired,
experienceDate: T.instanceOf(Date),
changeExperienceTime: T.func.isRequired,
experienceTime: T.string,
adults: T.number.isRequired,
kids: T.number.isRequired,
}
const mapStateToProps = state => ({
user: fromSocial.getUser(state),
detail: fromResource.getDetail(state, 'experience'),
experienceDate: fromUserSelections.getDate(state),
experienceTime: fromUserSelections.getTime(state),
adults: fromUserSelections.getAdults(state),
kids: fromUserSelections.getAdults(state),
})
const mapDispatchToProps = (dispatch) => ({
readDetail: (apiRequestParams) => dispatch(resourceDetailReadRequest('experience', { apiRequestParams })),
changeExperienceDate: (experienceDate) => dispatch(changeExperienceDate(experienceDate)),
changeExperienceTime: (experienceTime) => dispatch(changeExperienceTime(experienceTime)),
updateExperience: (availabilities) => dispatch(updateExperience('experience', availabilities))
})
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ExperienceDetailContainer))
Run Code Online (Sandbox Code Playgroud)
可以看出,我使用了 3 个钩子:useState、useWait、useEffect。它们都在顶级调用,而不是在条件或任何会破坏顺序的东西中调用。
我在这里有什么根本性的误解吗?
小智 0
您对钩子用法的理解是正确的,最可能的问题是您的getTimesForCurrentDate函数有条件地使用useState钩子。
React 的消息与您对钩子的使用相匹配 -useWait内部使用useContext并且 React 能够仅列出自己的钩子,这就是为什么有useState, useContext(不是useWait), useEffect。该函数是注册后在渲染中执行的唯一函数useEffect。
PS:从技术上讲,如果您在 props.match.params.cityid、...、键之一中有属性 getter 并在那里有条件地使用钩子,也可能会发生这种情况useState,但这感觉真的很糟糕;-)。
| 归档时间: |
|
| 查看次数: |
2774 次 |
| 最近记录: |