ProfileというネストされたReactコンポーネントがあります。完全なページリフレッシュでは、すべてのデータが正しく読み込まれますが、リンクをクリックして設定などの別のページに移動した後、プロファイルに戻ると、データは読み込まれません。私はリフレッシュ時に、componentWillReceivePropsが私のconsole.logを起動することに気付きましたが、リンクを使用すると起動しません。これは私のcreateContainerが正しくアンマウントしていないことが原因ですか?ネストされたReact + Meteorコンポーネントがページの負荷で小道具を受け取っていません
ピック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);
反応ルータコードは、これはreact-router/v3/docsからである
<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それから離れて移動するときは、すべてのコンポーネントがアンマウントされています。 –
生成された配列に固有のキーを追加してみてください。 –