私はリアクション・ルータ・ライフサイクルを使用して遷移を設定します。保存されていない変更があるフォームから移動しようとしたときにユーザーに知らせるためです。React.js、ES6、ES6クラス内の反応ルータライフサイクルへのアクセス方法
私はこの機能を使用することに特に興味があります:私は '反応し、ミックスイン' を構文を使用してみました
routerWillLeave(nextLocation) {
if(!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
}
:
reactMixin.onClass(ManageCoursePage, Lifecycle);
そして、私はこのエラーを取得する:
Invariant Violation: The Lifecycle mixin must be used on either a) a <Route component> or b) a descendant of a <Route component> that uses the RouteContext mixin
RouteComponentsとRouteContextに関して何かが欠けているようですね?
ManageCoursePage.js
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import reactMixin from 'react-mixin';
import { Lifecycle } from 'react-router';
import {authorsFormattedForDropdown} from '../../selectors/selectors';
import * as courseActions from '../../actions/courseActions';
import * as authorActions from '../../actions/authorActions';
import CourseForm from './CourseForm';
export class ManageCoursePage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
course: Object.assign({}, this.props.course),
errors: {},
saving: false
};
this.routerWillLeave = this.routerWillLeave.bind(this);
this.updateCourseState = this.updateCourseState.bind(this);
this.saveCourse = this.saveCourse.bind(this);
}
routerWillLeave(nextLocation) {
if(!this.state.isSaved)
return 'Your work is not saved! Are you sure you want to leave?'
}
componentWillReceiveProps(nextProps) {
if (this.props.course.id != nextProps.course.id) {
//Necessary to populate form when existing course is loaded directly
this.setState({course: Object.assign({}, nextProps.course)});
}
}
updateCourseState(event) {
const field = event.target.name;
let course = this.state.course;
course[field] = event.target.value;
console.log("change");
return this.setState({course: course});
}
courseFormIsValid() {
let formIsValid = true;
let errors = {};
if(this.state.course.title.length < 5) {
errors.title = 'Title must be at least 5 characters.';
formIsValid = false;
}
this.setState({errors: errors});
return formIsValid;
}
saveCourse(event){
event.preventDefault();
if (!this.courseFormIsValid()) {
return;
}
this.setState({saving: true});
this.props.actions.saveCourse(this.state.course)
.then(() => this.redirect())
.catch(error => {
toastr.error(error);
this.setState({saving: false});
});
}
redirect() {
this.setState({saving: false});
toastr.success('Course saved');
this.context.router.push('/courses');
}
render() {
return (
<CourseForm
allAuthors={this.props.authors}
onChange={this.updateCourseState}
onSave={this.saveCourse}
course={this.state.course}
errors={this.state.errors}
saving={this.state.saving}
/>
);
}
}
reactMixin.onClass(ManageCoursePage, Lifecycle);
ManageCoursePage.propTypes = {
course: PropTypes.object.isRequired,
authors: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired
};
ManageCoursePage.contextTypes = {
router: PropTypes.object
};
function getCourseById(courses, id){
const course = courses.filter(course => course.id == id);
if (course) return course[0]; //filter returns an array, so you have to grab the first value.
return null;
}
function mapStateToProps(state, ownProps) {
const courseId = ownProps.params.id; // from the path '/course/:id'
let course = {id: '', watchHref: '', title: '', authorId: '', length: '', category: ''};
if (courseId && state.courses.length > 0) {
course = getCourseById(state.courses, courseId);
}
return {
course: course,
authors: authorsFormattedForDropdown(state.authors)
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(courseActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ManageCoursePage);
routes.jsおそらく<Route />
コンポーネントでonLeave
小道具を使用することができます
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './components/App';
import HomePage from './components/home/HomePage';
import AboutPage from './components/about/AboutPage';
import CoursesPage from './components/course/CoursesPage';
import AuthorsPage from './components/author/AuthorsPage';
import ManageAuthorPage from './components/author/ManageAuthorPage';
import ManageCoursePage from './components/course/ManageCoursePage'; //eslint-disable-line import/no-named-as-default
export default (
<Route path="/" component={App}>
<IndexRoute component={HomePage} />
<Route path="about" component={AboutPage} />
<Route path="courses" component={CoursesPage} />
<Route path="course" component={ManageCoursePage} />
<Route path="course/:id" component={ManageCoursePage} />
<Route path="authors" component={AuthorsPage} />
<Route path="author" component={ManageAuthorPage} />
<Route path="author/:id" component={ManageAuthorPage} />
</Route>
);
あなたはonLeaveで何かを防ぐことはできません。 –