在 React 中将用户状态传递给子组件
Passing user state to child component in React
我有一个获取用户状态(登录或未登录)的父组件,应该能够将此状态传递给子组件并根据用户是否登录来显示 link已登录。但是,我无法将 loggedIn
状态传递给子组件,因此它可用于根据用户状态显示或隐藏 link:
父组件
class VideoPlayer extends React.Component {
constructor (props) {
super(props)
this.state = {
}
}
async componentDidMount () {
if (this.md.mobile()) {
this.setState({ blocking: 'mobile' })
} else if (this.browser.name === 'ie' || this.browser.name === 'edge') {
this.setState({ blocking: 'unsupported' })
} else {
try {
const userData = await superagent.get('/api/user')
if (!userData.error) {
this.setState({ user: userData.body })
}
const loggedIn = userData.body.success <==RETURNS FALSE IF USER IS LOGGED OUT AND "UNDEFINED" IF USER IS LOGGED IN
console.log(loggedIn)
} catch (err) {
console.log('Could not fetch user.', err)
}
this.fetchData()
}
}
/**
* render
*/
render () {
return (
<div className='video-player-container'>
{ this.state.blocking === 'paywall' &&
<Paywall
bgImgUrl={this.props.imageUrl('paywall-bg.png' )}
logoUrl={this.props.imageUrl('logo.png')}
loggedIn={!!this.state.user && this.state.user.success === undefined}
{...this.props}
/>
}
</div>
)
}
}
子组件
function Paywall (props) {
const { iconHrefs, logoUrl, bgImgUrl, config } = props
return (
<div
className='blocking-paywall'
style={{ backgroundImage: `url(${bgImgUrl})` }}>
<div className='container'>
<div className='logo'>
<img src={logoUrl} />
</div>
<h1 className='heading lg'>{content.heading}</h1>
<div className='message'>
<div className='subpara'>
content
</div>
<div className='subpara'>
catchphrase
</div>
</div>
<div className='login'>
{ !props.loggedIn && <==SHOULD ONLY SHOW LOGIN LINK IF USER IS NOT LOGGED IN
<p>already a member?<a href='/login'>Login</a></p>
}
</div>
</div>
</div>
)
}
您必须将 loggedIn 作为道具传递给付费墙,因为您没有将其作为父组件的道具,所以 {...this.props} 是不够的。
首先,您没有将 loggedIn
属性 传递给您的子组件
<Paywall
bgImgUrl={this.props.imageUrl('paywall-bg.png' )}
logoUrl={this.props.imageUrl('logo.png')}
{/* How did you expect child component to get loggedIn?*/}
loggedIn={!!this.state.user && this.state.user.success === undefined}
{...this.props}
/>
那么你的 Paywall
是 stateless 组件。它没有实例,你不能在渲染方法
中使用this
<div className='login'>
{ !props.loggedIn && <==SHOULD ONLY SHOW LOGIN LINK IF USER IS NOT LOGGED IN
<p>already a member?<a href='/login'>Login</a></p>
}
</div>
我有一个获取用户状态(登录或未登录)的父组件,应该能够将此状态传递给子组件并根据用户是否登录来显示 link已登录。但是,我无法将 loggedIn
状态传递给子组件,因此它可用于根据用户状态显示或隐藏 link:
父组件
class VideoPlayer extends React.Component {
constructor (props) {
super(props)
this.state = {
}
}
async componentDidMount () {
if (this.md.mobile()) {
this.setState({ blocking: 'mobile' })
} else if (this.browser.name === 'ie' || this.browser.name === 'edge') {
this.setState({ blocking: 'unsupported' })
} else {
try {
const userData = await superagent.get('/api/user')
if (!userData.error) {
this.setState({ user: userData.body })
}
const loggedIn = userData.body.success <==RETURNS FALSE IF USER IS LOGGED OUT AND "UNDEFINED" IF USER IS LOGGED IN
console.log(loggedIn)
} catch (err) {
console.log('Could not fetch user.', err)
}
this.fetchData()
}
}
/**
* render
*/
render () {
return (
<div className='video-player-container'>
{ this.state.blocking === 'paywall' &&
<Paywall
bgImgUrl={this.props.imageUrl('paywall-bg.png' )}
logoUrl={this.props.imageUrl('logo.png')}
loggedIn={!!this.state.user && this.state.user.success === undefined}
{...this.props}
/>
}
</div>
)
}
}
子组件
function Paywall (props) {
const { iconHrefs, logoUrl, bgImgUrl, config } = props
return (
<div
className='blocking-paywall'
style={{ backgroundImage: `url(${bgImgUrl})` }}>
<div className='container'>
<div className='logo'>
<img src={logoUrl} />
</div>
<h1 className='heading lg'>{content.heading}</h1>
<div className='message'>
<div className='subpara'>
content
</div>
<div className='subpara'>
catchphrase
</div>
</div>
<div className='login'>
{ !props.loggedIn && <==SHOULD ONLY SHOW LOGIN LINK IF USER IS NOT LOGGED IN
<p>already a member?<a href='/login'>Login</a></p>
}
</div>
</div>
</div>
)
}
您必须将 loggedIn 作为道具传递给付费墙,因为您没有将其作为父组件的道具,所以 {...this.props} 是不够的。
首先,您没有将 loggedIn
属性 传递给您的子组件
<Paywall
bgImgUrl={this.props.imageUrl('paywall-bg.png' )}
logoUrl={this.props.imageUrl('logo.png')}
{/* How did you expect child component to get loggedIn?*/}
loggedIn={!!this.state.user && this.state.user.success === undefined}
{...this.props}
/>
那么你的 Paywall
是 stateless 组件。它没有实例,你不能在渲染方法
this
<div className='login'>
{ !props.loggedIn && <==SHOULD ONLY SHOW LOGIN LINK IF USER IS NOT LOGGED IN
<p>already a member?<a href='/login'>Login</a></p>
}
</div>