为什么我对 Styled Components 的不当使用会导致超出调用堆栈大小
Why is my hacky use of Styled Components causing the call stack size to be exceeded
我正在使用 Gatsby 制作一个网站。我也在使用样式化的组件。
对于某个页面,设计者以他们无穷的智慧决定了某个按钮应该
1) 桌面页面顶部的 SHow
2) 显示在移动页面的底部。
因为我已经深入到这个项目中了,所以我不想用 absolute 来定位所有的东西。因为其他东西会坏。所以我试过了。
const SizeDetector = styled.div`
height: 0px;
width: 100%;
background-color: ${props => {
props.detectDesktopAndTablet()
return 'white'
}
}
@media (max-width: 450px) {
background-color: ${props => {
props.detectMobile()
return 'white'
}
}
}
`
class ContextualFrame extends React.Component {
constructor() {
super();
this.detectMobile = this.detectMobile.bind(this);
this.detectDesktopAndTablet = this.detectDesktopAndTablet.bind(this);
this.detectDesktopAndTablet = this.detectDesktopAndTablet.bind(this);
this.state = {'mobile': false, 'hasMounted': false}
}
detectMobile() {
this.setState({'mobile': true})
}
detectDesktopAndTablet() {
console.log('here')
this.setState({'mobile': false})
}
componentDidMount() {
this.setState({'hasMounted': true})
}
render() {
let {mobile, hasMounted} = this.state
return (
<div>
{
hasMounted ? (<SizeDetector detectDesktopAndTablet={this.detectDesktopAndTablet} detectMobile={this.detectMobile} />) : null
}
{
mobile ? null : (<MeetPeopleButton text={'Meet The Team'} />)
}
{this.props.children}
{
mobile ? (<MeetPeopleButton text={'Meet The Team'} />) : null
}
</div>
)
}
}
这导致错误:
RangeError: Maximum call stack size exceeded
detectDesktopAndTablet 的控制台日志中的 'here' 被调用了数千次。
为什么会这样?我猜这可能是由于 Styled Components 或 React 工作的某种特定方式而发生的。要求增加我对 React 工作原理的理解。
也许我已经解决了您的问题。就是在渲染过程中,你正在改变你的组件的状态,让它再次渲染,等等:
ContextualFrame.render()
-> 调用 SizeDetector.render()
-> 调用 detectDesktopAndTablet()
-> 调用 setState(...)
-> 过程 ContextualFrame.render()
要解决此问题,请在设置之前检查 属性 是否相同:
detectDesktopAndTablet() {
console.log('here')
if(this.state.mobile !== false) this.setState({'mobile': false})
}
我正在使用 Gatsby 制作一个网站。我也在使用样式化的组件。
对于某个页面,设计者以他们无穷的智慧决定了某个按钮应该 1) 桌面页面顶部的 SHow 2) 显示在移动页面的底部。 因为我已经深入到这个项目中了,所以我不想用 absolute 来定位所有的东西。因为其他东西会坏。所以我试过了。
const SizeDetector = styled.div`
height: 0px;
width: 100%;
background-color: ${props => {
props.detectDesktopAndTablet()
return 'white'
}
}
@media (max-width: 450px) {
background-color: ${props => {
props.detectMobile()
return 'white'
}
}
}
`
class ContextualFrame extends React.Component {
constructor() {
super();
this.detectMobile = this.detectMobile.bind(this);
this.detectDesktopAndTablet = this.detectDesktopAndTablet.bind(this);
this.detectDesktopAndTablet = this.detectDesktopAndTablet.bind(this);
this.state = {'mobile': false, 'hasMounted': false}
}
detectMobile() {
this.setState({'mobile': true})
}
detectDesktopAndTablet() {
console.log('here')
this.setState({'mobile': false})
}
componentDidMount() {
this.setState({'hasMounted': true})
}
render() {
let {mobile, hasMounted} = this.state
return (
<div>
{
hasMounted ? (<SizeDetector detectDesktopAndTablet={this.detectDesktopAndTablet} detectMobile={this.detectMobile} />) : null
}
{
mobile ? null : (<MeetPeopleButton text={'Meet The Team'} />)
}
{this.props.children}
{
mobile ? (<MeetPeopleButton text={'Meet The Team'} />) : null
}
</div>
)
}
}
这导致错误:
RangeError: Maximum call stack size exceeded
detectDesktopAndTablet 的控制台日志中的 'here' 被调用了数千次。
为什么会这样?我猜这可能是由于 Styled Components 或 React 工作的某种特定方式而发生的。要求增加我对 React 工作原理的理解。
也许我已经解决了您的问题。就是在渲染过程中,你正在改变你的组件的状态,让它再次渲染,等等:
ContextualFrame.render()
-> 调用 SizeDetector.render()
-> 调用 detectDesktopAndTablet()
-> 调用 setState(...)
-> 过程 ContextualFrame.render()
要解决此问题,请在设置之前检查 属性 是否相同:
detectDesktopAndTablet() {
console.log('here')
if(this.state.mobile !== false) this.setState({'mobile': false})
}