首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当状态的特定部分丢失时,如何阻止导航到组件?

问当状态的特定部分丢失时,如何阻止导航到组件?
EN

Stack Overflow用户
提问于 2017-07-16 16:35:50
回答 2查看 59关注 0票数 2

首先,请原谅这个措辞不佳的问题。

我有一个SPA,它有一个包含以下路由的页面:

/students

此页面的容器是StudentsView.js,我在其中执行以下操作以获取学生列表:

代码语言:javascript
复制
  componentDidMount () {
    this.props.actions.loadStudents()
  }

这是一个学生列表,单击一个将根据学生ID进入该学生的详细信息页面:

/student/5

此页面的组件是StudentDetailView.js

现在,为了避免不必要的应用程序调用以提高初始应用程序加载期间的性能,我没有调度对loadStudents()操作的调用,因为该页面不是我的应用程序的主页。

现在的问题是,当用户导航到学生详细信息页面时,例如:

/student/5

然后刷新页面,因为它们位于不同的组件上,并且StudentsView.js组件的componentDidMount()不再被调用,所以我的状态中有一个空的学生数组,所以在我的学生详细信息组件中,学生将是未定义的:

代码语言:javascript
复制
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()操作之外,有没有办法解决这个问题?

最佳实践是什么?如果students列表为空,我是否要将用户导航回列表页面?有没有一种方法,是否建议我在StudentDetailView.js组件中分离loadStudents()操作?

基本上,当用户在StudentDetailView.js上时,我如何确保始终填充状态的学生部分

谢谢你的帮助。

EN

回答 2

Stack Overflow用户

发布于 2017-07-16 17:10:25

我相信你正在使用redux,所以在你的StudentDetail组件中,你可以分派一个动作,比如loadStudentById(5),在你的动作中,你可以检查loadStudents返回的数据是否可用,如果不能,你可以先loadStudents,然后是loadStudent()。

代码语言:javascript
复制
//somewhere in your actions
function loadStudent(studentId) {
  return (dispatch, getState) => {
    dispatch(loadStudents()).then(() => {
      const students = getState().students.get('students')
      const student = students.find(s => s.id === studentId)

      // This action will set the student in reducer when type is matched
      dispatch(setStudent(student))
    })
  }
}

所以setStudent可能是这样的

代码语言:javascript
复制
function setStudent(student) {
  return {
    type: 'SET_STUDENT',
    payload: student
  }
}

要检查学生是否已经有空,并避免在loadStudents中调用API,可以这样做。

代码语言:javascript
复制
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
  }
}
票数 1
EN

Stack Overflow用户

发布于 2017-07-16 23:26:35

我认为现在实现这一点的最好方法是在学生详细信息组件上分派一个loadStudentById()操作。我可以在componentDidMount()中做这件事

代码语言:javascript
复制
  componentDidMount () {
    const studentId = this.props.params.id
    this.props.actions.loadStudentById(studentId)
  }

事实证明,the seed project I'm using有一种独特的异步加载路由的方法,他们建议不要使用生命周期钩子来阻碍检索数据的操作。基本上,只有在路由匹配之后才加载组件,此时我可以截获此钩子,并在加载组件之前分派一个getStudentById()操作。类似于:

代码语言:javascript
复制
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')
  }
})

更多详细信息请点击此处:

Populating a Component On Load

这个项目的创建者采用了一种非常时髦的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45126619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档