对React来说有点新,并在下面编写了这段代码。下面的组件用于渲染故事的时间和日期选择器。时间和日期选择器仅为那些计划出现故事的社交媒体呈现。
class TaleScheduler extends Component {
constructor(props) {
super(props);
this.state = {
returnData: {},
totalNeeded: numberOfChannels(this.props.data)
};
}
setSchedule = (date, channel) => {
const returnData = update(this.state.returnData, {
$merge: {channel: date}
})
this.setState({returnData: returnData})
const { data, ScheduleTale } = this.props
if (Object.values(this.state.returnData).length === this.state.totalNeeded) {
FireAction(this.state.returnData, data.id)
}
}
render() {
const { data } = this.props
return (
<div style={{"display": "inline-block"}}>
{data.showOnFacebook ? (<DateTimePicker data={data} image={facebook} setSchedule={this.setSchedule} />) : null}
{data.showOnTwitter? (<DateTimePicker data={data} image={instagram} setSchedule={this.setSchedule} />) : null}
{data.showOnInstagram ? (<DateTimePicker data={data} image={twitter} setSchedule={this.setSchedule} />) : null}
{data.showOnApp ? (<DateTimePicker data={data} image={app} setSchedule={this.setSchedule} />) : null}
<FlatButton label="Schedule" onClick={this.setSchedule} />
</div>
)
}
}
这会根据故事的显示位置呈现一组时间和日期选择器。下面是正在显示的组件
class DateTimePicker extends Component {
constructor(props) {
super(props);
this.state = {
date: null,
time: null
};
}
handleDateInput = (event, date) => {
this.setState({
date: date
})
}
handleTimeInput = (event, time) => {
this.setState({
time: time
})
}
componentDidUpdate(prevProps, prevState) {
const {setSchedule, channel} = this.props
if (this.state.date && this.state.time) {
setSchedule(concatenateDateAndTime(this.state.date, this.state.time), channel)
}
}
render() {
return (
<List>
<ListItem
leftAvatar={
<img src={this.props.image} style={styles.scheduledChannelImgStyle} />
}>
</ListItem>
<ListItem>
<DatePicker onChange={this.handleDateInput} />
</ListItem>
<ListItem>
<TimePicker onChange={this.handleTimeInput} />
</ListItem>
</List>
)
}
}
选择上面的日期和时间。整个页面锁定一个无限循环,导致页面冻结。我确信这些函数正在循环中相互调用。但我不太了解React渲染能够弄清楚原因。
答案 0 :(得分:1)
原因是您在setSchedule
生命周期方法中调用方法componentDidUpdate
。 setSchedule
方法正在调用setState()
。这导致拨打componentDidUpdate
,随后再次呼叫setState
。你正在创建一个无限循环,因为没有中断条件。您可以在componentWillReceiveProps
内调用setState而不是componentDidUpdate
。
componentDidUpdate(prevProps, prevState) {
const {setSchedule, channel} = this.props
if (this.state.date && this.state.time) {
setSchedule(concatenateDateAndTime(this.state.date, this.state.time), channel)//Calling method that calls setstate.
}
}
答案 1 :(得分:1)
在调用函数之前componentDidUpdate
检查previous date and time state values
,否则每当定义日期和时间并且组件正在更新时,只要你调用{{1函数,因为它更新状态和父元素,其中inturn导致更新的道具传递给子组件。
尝试
setSchedule
要确认调用子组件componentDidUpdate(prevProps, prevState) {
const {setSchedule, channel} = this.props
if(prevState.date !== this.state.data || prevState.time !== this.state.time) {
if (this.state.date && this.state.time) {
setSchedule(concatenateDateAndTime(this.state.date, this.state.time), channel)
}
}
}
的父组件中的任何更新,请查看此代码段
componentDidUpdate
&#13;
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
clicked: false
}
}
render() {
return (
<div>
<Child />
<button onClick={() => this.setState((prevState) => ({clicked: !prevState.clicked}))} > Toggle</button>
</div>
)
}
}
class Child extends React.Component {
componentDidUpdate(prevProps, prevState) {
console.log('update in child called');
}
render() {
return (
<div>
Hello Child
</div>
)
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'));
&#13;