2017-07-16 36 views
2

首先,請原諒措辭不佳的問題。如何在特定部分狀態丟失時防止導航到組件?

我有與這條路線頁面的SPA:

/students

該頁面的容器是StudentsView.js,這裏面我這樣做是爲了讓學生的名單:

componentDidMount() { 
    this.props.actions.loadStudents() 
    } 

這是一個學生名單,點擊一個會根據你的學生ID做出學生的詳細頁面:

/student/5

該頁面的組件是StudentDetailView.js

現在,以避免不必要的API調用初始應用負載時提高性能,我還沒有分派到loadStudents()行動的呼籲,其從設置狀態的學生部分API調用,因爲此頁面不是我的應用程序的主頁面。現在

問題是,當用戶瀏覽到一個學生的詳細信息頁說:

/student/5

再刷新頁面,因爲它們是在不同的組件和StudentsView.js組件的componentDidMount()不再所謂的,我結束了我的狀態的空數組的學生,所以在我的學生細節分量學生將是不確定的:

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 
    } 
} 

有大約t的一種工作方式他除了確保loadStudensts()操作在初始應用程序加載中被調用?

什麼是最佳做法,如果students列表爲空,是否將用戶導航回列表頁面?有沒有辦法,是否推薦我在StudentDetailView.js組件中分解loadStudents()動作?

基本上,我如何確保學生的狀態部分總是在用戶在StudentDetailView.js時填充?

感謝您的任何幫助。

回答

1

我相信你正在使用終極版,所以在你StudentDetail組件,您可以派遣一個動作說loadStudentById(5),並在你的行動,你可以檢查,如果沒有你可以,你可以先loadStudents其次loadStudent()通過loadStudents可用返回的數據。

//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就應該像這樣

function setStudent(student) { 
    return { 
    type: 'SET_STUDENT', 
    payload: 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 
    } 
} 
0

我想現在最好的方法是在學生細節組件上派發loadStudentById()動作。我能做到這裏面componentDidMount()

componentDidMount() { 
    const studentId = this.props.params.id 
    this.props.actions.loadStudentById(studentId) 
    } 

原來the seed project I'm using必須加載路線的獨特方法異步,他們建議不要使用生命週期掛鉤dispacth行動檢索數據。基本上只在路由匹配後加載組件,此時我可以攔截該鉤子並在加載組件之前分發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') 
    } 
}) 

更多細節在這裏:

Populating a Component On Load

本項目的創造者,一個非常時尚的方式。

相關問題