我有一個名爲Profile的嵌套React組件。在整個頁面刷新所有的數據加載正確,但是當我點擊一個鏈接帶我到另一個頁面,如設置,然後導航回配置文件,沒有數據加載。我注意到刷新時,componentWillReceiveProps觸發我的console.log,但是當我使用鏈接時它不會觸發。我想知道這是否是由於我的createContainer沒有正確卸載?嵌套React +流星組件在頁面加載時未收到道具
圖片1:個人資料上完全刷新和載荷接收道具正確。 圖2:我導航到設置,一切正常。 圖3:我導航回到配置文件並且沒有加載,componentWillReceiveProps未被觸發
這些組件是使用反應路由器的嵌套路由。但我很困惑如何設置工作正常,沒有明顯的代碼差異。
任何幫助非常感謝,謝謝!
ProfileContainer.js
import React, { Component } from 'react';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import introJs from 'intro.js';
import { browserHistory } from 'react-router';
import '../../../../../node_modules/intro.js/introjs.css';
// Custom
import ProfileForm from './ProfileForm';
import { countryList, statesList, industryList, incomesList, monthsList, educationsList, ofAgeCheck } from '../../../../modules/helpers.js';
import { upsertUserProfile } from '../../../../../imports/api/methods/profile/settingsMethods';
import { changeIntroTour } from '../../../../api/methods/user/userMethods';
// Collections
import { UserProfile } from '../../../../api/collections/profile/userProfileCollection';
import { IntroTour } from '../../../../api/collections/user/introTourCollection';
const expertiseOptions = [];
const dayOptions = [];
const yearOptions = [];
const profileIntro = {
text: 'Tell us a little about yourself.',
};
const tourObj = {
userId: Meteor.userId(),
page: 'profile',
};
class ProfileFormContainer extends Component {
constructor() {
super();
const NA = 'N/A';
this.state = {
firstView: NA,
birthmonth: NA,
birthday: NA,
birthyear: NA,
sex: NA,
expertise: '',
country: '',
state: '',
industry: '',
income: '',
education: '',
showTour: false,
tourRunning: false,
};
}
componentDidMount() {
this.loadExpertiseOptions();
this.loadBirthdateOptions();
this.handleChange = this
.handleChange
.bind(this);
this.upsertToDB = this
.upsertToDB
.bind(this);
}
componentWillUnmount() {
introJs.introJs().exit();
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
this.existingSettings(nextProps);
if (nextProps.intro.length > 0) {
this.setState({
showTour: nextProps.intro[0].profileTour,
},() => {
if (!this.state.tourRunning) {
this.runTour();
}
});
}
}
runTour() {
if (this.state.showTour === true) {
this.setState({
tourRunning: true,
});
introJs.introJs().setOption('doneLabel', 'Next').start().oncomplete(() => {
changeIntroTour.call(tourObj);
browserHistory.push('/user/settings');
})
.onexit(() => {
changeIntroTour.call(tourObj);
});
}
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value,
});
}
existingSettings(data) {
const user = data.profile[0];
this.setState({
birthmonth: user.birthmonth,
birthday: user.birthday,
birthyear: user.birthyear,
sex: user.sex,
expertise: user.expertise,
country: user.country,
state: user.state,
industry: user.industry,
income: user.income,
education: user.education,
});
}
loadExpertiseOptions() {
for (let i = 1; i <= 10; i++) {
expertiseOptions.push(
<option key={ i } value={ i }>
{ i }
</option>
);
}
}
loadBirthdateOptions() {
this.loadDayOptions();
this.loadYearOptions();
}
loadDayOptions() {
dayOptions.push(
<option key={ ' ' } value={ ' ' }>
</option>
);
for (let i = 1; i <= 31; i++) {
dayOptions.push(
<option key={ i } value={ i }>
{ i }
</option>
);
}
}
loadYearOptions() {
yearOptions.push(
<option key={ ' ' } value={ ' ' }>
</option>
);
for (let i = new Date().getFullYear(); i >= 1900; i--) {
yearOptions.push(
<option key={ i } value={ i }>
{ i }
</option>
);
}
}
upsertToDB() {
if (ofAgeCheck(13, this.state.birthmonth, this.state.birthday, this.state.birthyear)) {
Bert.alert('If you are under 13 years of age, then please do not use the service.', 'danger');
} else if (this.state.birthday === 'N/A' || this.state.birthmonth === 'N/A' || this.state.birthyear === 'N/A' || this.state.sex === 'N/A') {
Bert.alert('Please complete all required fields.', 'danger');
} else {
const birthdateFormatted = `${this.state.birthmonth}-${this.state.birthday}-${this.state.birthyear}`;
const settingsObj = {
userId: Meteor.userId(),
birthmonth: this.state.birthmonth,
birthday: this.state.birthday,
birthyear: this.state.birthyear,
birthdate: birthdateFormatted,
sex: this.state.sex,
expertise: this.state.expertise,
country: this.state.country,
state: this.state.state,
industry: this.state.industry,
income: this.state.income,
education: this.state.education,
};
upsertUserProfile.call(settingsObj, (error, response) => {
if (error) {
Bert.alert('Save unsuccessful.', 'danger');
} else {
if (this.state.tourRunning) {
changeIntroTour.call(tourObj);
browserHistory.push('/user/settings');
}
Bert.alert('Save successful!', 'success');
}
});
}
}
render() {
const countries = countryList();
const states = statesList();
const industries = industryList();
const incomes = incomesList();
const months = monthsList();
const educations = educationsList();
if (!this.props.ready) {
return (
<div>Loading user profile...</div>
);
}
return (
<ProfileForm {...this.state} months={ months } dayOptions={ dayOptions } yearOptions={ yearOptions } expertise={ expertiseOptions } countries={ countries }
states={ states } industries={ industries } incomes={ incomes } educations={ educations } handleChange={ this.handleChange } upsertToDB={ this.upsertToDB }
profileIntro={ profileIntro } />
);
}
}
ProfileFormContainer.PropTypes = {
ready: React.PropTypes.bool,
profile: React.PropTypes.array,
};
export default createContainer(() => {
const userProfile = Meteor.subscribe('userProfile', Meteor.userId());
const introTour = Meteor.subscribe('introTour', Meteor.userId());
return {
ready: userProfile.ready(),
profile: UserProfile.find({}).fetch(),
intro: IntroTour.find({}).fetch(),
};
}, ProfileFormContainer);
下面是反應路由器的代碼
<Router history={browserHistory}>
<Route name="Home" path="/" component={Main} >
<IndexRoute component={Index} onEnter={authenticate} />
<Route name="Asset Allocation" path="/asset-allocation"
component={AssetAllocation} />
<Route name="Recover Password" path="/recover-password"
component={RecoverPassword} />
<Route name="Reset Password" path="/reset-password/:token"
component={ResetPassword} />
<Route name="User" path="/user" component={Profile}>
<Route name="About" path="/user/home" component={User} />
<Route name="Profile" path="/user/profile" component=
{ProfileForm} />
<Route name="Settings" path="/user/settings" component=
{SettingsForm} />
</Route>
</Route>
<Route component={Blank}>
<Route name="Login" path="/login" component={Login} onEnter=
{loggedIn} />
<Route name="Signup" path="/signup" component={Signup} onEnter=
{loggedIn} />
<Route name="Not Found" path="*" component={NotFound} onEnter=
{notFound} />
</Route>
</Router>,
試試這個。在您的ProfileContainer中添加一個componentWillUnmount方法,並在其中放置一個'console.log(「unmounting」);'行。然後檢查它是否卸載,當你離開它。 –
@KyleRichardson所有組件在離開時都會卸載。 –
嘗試爲youtr生成的數組添加唯一鍵。 –