Reactjs 当状态的特定部分丢失时,如何防止导航到组件?
首先,请原谅这个措辞拙劣的问题 我有一个SPA,它有一个页面,上面有以下路线:Reactjs 当状态的特定部分丢失时,如何防止导航到组件?,reactjs,redux,react-router,react-redux,Reactjs,Redux,React Router,React Redux,首先,请原谅这个措辞拙劣的问题 我有一个SPA,它有一个页面,上面有以下路线: /students 此页面的容器是StudentsView.js,在其中我这样做是为了获得学生列表: componentDidMount () { this.props.actions.loadStudents() } 这是一个学生列表,单击其中一个将根据学生ID进入该学生的详细信息页面: /student/5 此页面的组件是StudentDetailView.js 现在为了避免不必要的API调用来
/students
此页面的容器是StudentsView.js
,在其中我这样做是为了获得学生列表:
componentDidMount () {
this.props.actions.loadStudents()
}
这是一个学生列表,单击其中一个将根据学生ID进入该学生的详细信息页面:
/student/5
此页面的组件是StudentDetailView.js
现在为了避免不必要的API调用来提高初始应用程序加载期间的性能,我没有向loadStudents()
操作发送调用,该操作通过API调用设置状态的学生部分,因为此页面不是我的应用程序的主页面
现在的问题是,当用户导航到学生详细信息页面时,会说:
/student/5
然后刷新页面,因为它们位于不同的组件上,并且不再调用StudentsView.js
组件的componentDidMount()
,因此在我的状态下,我会得到一个空的students数组,因此在我的students详细信息中,组件student将是未定义的:
function mapStateToProps (state, ownProps) {
const studentId = +ownProps.params.id
let student = { id: '', firstName: '', lastName: '' }
if (studentId && state.students.length > 0) {
student = getStudentById(state.students, studentId)
}
return {
student: student
}
}
除了确保在初始应用程序加载中调用loadStudensts()
操作外,还有其他解决方法吗
最佳做法是什么?如果学生列表为空,我是否将用户导航回列表页面?有没有办法,建议我取消StudentDetailView.js
组件中的loadStudents()
操作
基本上,当用户在StudentDetailView.js
上时,如何确保始终填充状态的学生部分
谢谢您的帮助。我相信您正在使用redux,因此在StudentDetail组件中,您可以发送一个操作,比如说loadStudentById(5)
,在操作中,您可以检查loadStudents
返回的数据是否可用,如果不可用,您可以先loadStudents
,然后是loadStudent()
所以setStudent
可能是
function setStudent(student) {
return {
type: 'SET_STUDENT',
payload: student
}
}
要检查student是否已经可用,并避免loadStudents中的API调用,您可以执行类似操作
function loadStudents() {
return (dispatch, getState) => {
const students = getState().students.get('students')
// Return early avoiding API call
if (students && students.length > 0) {
return Promise.resolve()
}
// actual API loading logic here
}
}
经过深思熟虑后,我认为现在实现这一点的最佳方法是对student detail组件分派loadStudentById()
操作。我可以在componentDidMount()中执行此操作:
事实证明,它有一种独特的异步加载路由的方法,他们建议不要使用生命周期挂钩来显示操作以检索数据。基本上,只有在路由匹配之后才能加载组件,在这一点上,我可以截获这个钩子,并在加载组件之前调度一个getStudentById()
操作。比如:
import { loadStudentById } from '../../actions/studentActions'
export default (store) => ({
path : 'student/:id',
getComponent (nextState, cb) {
require.ensure([], (require) => {
const studentId = nextState.params.id
store.dispatch(loadStudentById(studentId))
const student = require('./components/StudentDetailView').default
cb(null, student)
}, 'student')
}
})
详情如下:
这个项目的创作者采用了一种非常圆滑的方法
componentDidMount () {
const studentId = this.props.params.id
this.props.actions.loadStudentById(studentId)
}
import { loadStudentById } from '../../actions/studentActions'
export default (store) => ({
path : 'student/:id',
getComponent (nextState, cb) {
require.ensure([], (require) => {
const studentId = nextState.params.id
store.dispatch(loadStudentById(studentId))
const student = require('./components/StudentDetailView').default
cb(null, student)
}, 'student')
}
})