编辑:经过进一步测试,我意识到 componentDidMount 的行为符合我的预期,但我的随机函数似乎有问题,如果它第二次运行,由于某种原因返回未定义,所以在初始挂载它给我结果,当我再次挂载它时它返回未定义,因此没有任何渲染......
我已进行研究以了解我遇到此问题的原因。我有一个 webapp 组件,它只是一个将呈现赞助商名称的横幅。每次呈现此横幅时,我都想随机化赞助商出现的顺序。我可以让它工作,但它只在第一次渲染时发生(在 componentDidMount() 上),然后每次我访问渲染该组件的任何部分时,它不再调用 componentDidMount(),因此它不渲染任何内容。
起初我认为每次进入调用该组件的部分时都应该调用 componentDidMount()。看了一圈,到处都说组件被挂载一次,这就是为什么它只调用一次函数。我怎样才能让它在我每次渲染组件时随机化?
这是我正在编写的代码示例。
class SponsorBanner extends React.Component {
constructor(props){
super(props)
this.state = {
randomized: []
}
this.randomizeSponsors = this.randomizeSponsors.bind(this)
}
randomizeSponsors(){
let copy = []
const array = ['a','b','c','d']
let n = array.length
let i;
while(n){
i = Math.floor(Math.random() * n--)
copy.push(array.splice(i,1)[0])
}
let randomizedArray = copy.map((sponsor,i) => <div key={i}>{sponsor}</div>)
this.setState({randomized:randomizedArray})
}
componentDidMount(){
this.randomizeSponsors()
}
render(){
return (
<div>
{this.state.randomized}
</div>
)
}
}
此组件在应用程序的 2 个不同部分呈现。这是一个非常简单的应用程序,我什至没有向它添加路由。它完全可以作为 SPA 使用。当用户单击一个部分时,它会呈现该组件。在第一次加载时,如果我访问呈现此组件的部分,它会显示一个随机数组。如果我导航到另一个部分并返回,它会呈现一个空横幅。
为什么会发生这种情况,我该如何解决???
最佳答案
另一种方法可能是使用 setIterval
,如果您希望它每 x 个 毫秒
改变一次。
工作示例:https://codesandbox.io/s/k9zz9wq9lo
import random from "lodash/random";
import React, { Component } from "react";
export default class Banner extends Component {
state = {
randomIndex: 0
};
componentDidMount = () => this.setTimer();
componentWillUnmount = () => this.clearTimer();
clearTimer = () => clearInterval(this.timeout);
timer = () => this.setState({ randomIndex: random(0, 999) });
setTimer = () => (this.timeout = setInterval(this.timer, 3000));
render = () => (
<img
src={`https://loremflickr.com/600/100?lock=${this.state.randomIndex}`}
/>
);
}
或者,如果您不想使用 setIterval
并且此组件始终处于挂载状态...并且您只希望它在状态更改时更改...那么使用 HOC
组件管理状态。然后,您可以利用 HOC
的 render
方法来更新变量。
工作示例:https://codesandbox.io/s/6qvl49vqw
import random from "lodash/random";
import React, { Component } from "react";
import Sample from "./Sample";
export default class Parent extends Component {
state = {
loadC1: false
};
shouldComponentUpdate = (nextProps, nextState) =>
this.state.loadC1 !== nextState.loadC1;
handleClick = () =>
this.setState(prevState => ({ loadC1: !this.state.loadC1 }));
render = () => {
const randomIndex = random(0, 999);
const { loadC1 } = this.state;
return (
<div style={{ textAlign: "center" }}>
<button
className="uk-button uk-button-primary"
onClick={this.handleClick}
>
{!loadC1 ? "Show" : "Hide"} Component
</button>
<div style={{ marginBottom: 40 }}>
{loadC1 && <Sample />}
</div>
<img src={`https://loremflickr.com/600/100?lock=${randomIndex}`} />
</div>
);
};
}
关于javascript - 每次渲染组件时调用一个函数,因为 componentDidMount() 只触发一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52527513/