2016-08-25 22 views
5

Muszę wyświetlić tabelę z dużą ilością danych. Jest przycisk paginacji, który wyświetla 10 rekordów na stronę. Mam jeden przycisk o nazwie "FETCH", którego kliknięcie powoduje zapełnienie tabeli. Jak załadować mój stół na ładowanie strony.Jak wysłać akcję po wczytaniu strony w trybie reakcji-redux?

action.js

import fetch from 'isomorphic-fetch'; 
export const ADD_BENEFICIARY = 'ADD_BENEFICIARY'; 
export const REMOVE_BENEFICIARY = 'REMOVE_BENEFICIARY'; 

export const ADD_PLAN_TO_COMPARE = 'ADD_PLAN_COMPARE'; 
export const REMOVE_PLAN_FROM_COMPARE = 'REMOVE_PLAN_COMPARE'; 
export const SHOW_PLAN_COMPARE = 'SHOW_PLAN_COMPARE'; 

export const NEXT_PAGE_PLAN_LIST = 'NEXT_PAGE_PLAN_LIST'; 
export const PREV_PAGE_PLAN_LIST = 'PREV_PAGE_PLAN_LIST'; 
export const REQUEST_PAGE_PLAN_LIST = 'REQUEST_PAGE_PLAN_LIST'; 
export const RECEIVE_PAGE_PLAN_LIST = 'RECEIVE_PAGE_PLAN_LIST'; 

export const showNextPageOfPlans =() => { 

    return { 
    type: NEXT_PAGE_PLAN_LIST 
    } 
} 

export const showPreviousPageOfPlans =() => { 

    return { 
    type: PREV_PAGE_PLAN_LIST 
    } 
} 

export const requestPageOfPlans = (startIdx, pageSize) => { 

    return { 
    type: REQUEST_PAGE_PLAN_LIST, 
    start: startIdx, 
    pageSize: pageSize 
    } 
} 

export const receivePageOfPlans = (startIdx, json) => { 

    return { 
    type: RECEIVE_PAGE_PLAN_LIST, 
    start: startIdx, 
    plans: json 
    } 
} 


export const fetchPlans = (startIdx, pageSize) => { 

    var str = sessionStorage.getItem('formValue'); //JSON.stringify(formValues); 

    return function (dispatch) { 
    dispatch(requestPageOfPlans(startIdx, pageSize)); 
    return fetch('http://172.16.32.57:9090/alternatePlans/plans/list/', {method: 'post', body: str, headers: new Headers({'Content-Type': 'application/json'}) }) 
     .then(response => response.json()) 
     .then(json => 
     dispatch(receivePageOfPlans(startIdx, json)) 
    ) 
    } 
} 

reducer.js

import { REQUEST_PAGE_PLAN_LIST, RECEIVE_PAGE_PLAN_LIST, 
     NEXT_PAGE_PLAN_LIST, PREV_PAGE_PLAN_LIST } from './actions'; 

const initialPaging = { 

    startIndex: 0, 
    lastIndex: 0, 
    pageSize: 10 
} 

const paging = (state = initialCurrentPage, action) => { 

    switch (action.type) { 

    case NEXT_PAGE_PLAN_LIST: 

     if (state.startIndex+state.pageSize <= state.lastIndex) { 

     return { ...state, startIndex: state.startIndex+state.pageSize }; 
     } 
     else { 

     return state; 
     } 

    case PREV_PAGE_PLAN_LIST: 

     if (state.startIndex-state.pageSize >= 0) { 

     return { ...state, startIndex: state.startIndex-state.pageSize }; 
     } 
     else { 

     return state; 
     } 

    case REQUEST_PAGE_PLAN_LIST: 

     return { ...state, isFetching: true }; 

    case RECEIVE_PAGE_PLAN_LIST: 

     return { ...state, isFetching: false }; 

    default: 
     return state; 
    } 

} 

var initialPlans = []; 

const plans = (state = initialPlans, action) => { 

    switch (action.type) { 

    case RECEIVE_PAGE_PLAN_LIST: 
     return action.plans.plans; 

    default: 
     return state; 
    } 
} 


const allReducers = (state = {}, action) => { 

    let items = plans(state.plans, action); 
    return { 
    plans: items, 
    paging: paging({ ...initialPaging, ...state.paging, lastIndex: items.length-1 }, action) 
    } 
} 

export default allReducers; 

PS: Jestem nowy w reakcji-redux. Oficjalna dokumentacja jest dobra, ale podaje się mniej wyjaśnienia.

Odpowiedz

4

Wywołujesz go z componentDidMount() komponentu reagowania na swoją stronę lub w dowolnym miejscu. W tym pliku komponentu:

import { requestPageOfPlans } from 'actions'; 
import React from 'react'; 
import { connect } from 'react-redux'; 

class MyComponent extends React.Component { 
    componentDidMount() { 
    this.props.requestPageOfPlans(); 
    } 
} 

export default connect((state) => state, { requestPageOfPlans })(MyComponent); 

Kluczem jest tutaj konfiguracja połączenia. Pierwszym parametrem jest sposób przekształcania stanu (twoich reduktorów) w dane dla rekwizytów. Dostosuj to tak, jak potrzebujesz. Drugi to czynności, które chcesz związać. Możesz także importować wysyłkę ręcznie, ale ja osobiście lubię ten wzór. Ustawia akcje jako rekwizyty na komponencie i możesz to tak nazwać. Po prostu przekazuj do niego argumenty, tak jak potrzebujesz. Ta strona tutaj: https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options wyjaśnia bardziej szczegółowo funkcję łączenia.

Edit

Biorąc jesteś Stronicowanie na przednim końcu, trzeba dostosować połączyć mapStateToProps funkcji, aby przekazać dane paginacji do komponentu, a następnie pętli to co Cię do wyświetlenia potrzeba. Osobiście zrobiłbym paginację na zapleczu i po prostu wykonuję nowe żądania dla każdej strony. Zależy od liczby rekordów, które spodziewasz się mieć.

Więc connect zrobić coś takiego:

export default connect((state) => { 
    return { 
    startIndex: state.paging.lastIndex, 
    pageSize: state.paging.pageSize, 
    lastIndex: state.paging.lastIndex, 
    plans: state.plans 
    }; 
}, { requestPageOfPlans })(MyComponent); 

Następnie w składniku, Loop Through planów wykorzystania tych indeksów:

render() { 
    const plans = []; 
    const maxIndex = Math.min(this.props.startIndex + this.props.pageSize, this.props.lastIndex); 
    for (let i = this.props.startIndex || 0; i < maxIndex; i++) { 
    const plan = this.props.plans[i]; 
    plans.push(<Plan key={plan.id} plan={plan} />); 
    } 

    return (
    <ul>{plans}</ul> 
    ); 
} 

wprowadzenie pewnych założeń znowu na jak zamierzasz uczynić to, jeśli masz komponent o nazwie Plan, itd. Ale w przybliżeniu możesz z nim pracować.

+0

importować {requestPageOfPlans} z "reduktorów"; Wpisałem to w ten sposób. import {requestPageOfPlans} from 'action'; Pobiera cały wynik i nie działa z powodu tej strony. –

+0

Ach, przepraszam, tak, nie patrzyłem uważnie, żeby zobaczyć tam nazwy plików. Wiedziałem, że będę tam fudge trochę importu. Wprowadzono zmiany w celu dalszego wyjaśnienia, w jaki sposób można potencjalnie pracować z danymi. – agmcleod

0

componentDidMount to dobry czas na załadowanie pierwszej strony.

BTW, Moim zdaniem zmiana strony nie jest działaniem, to tylko niektóre parametry ładowania danych.

ActionCreator

const userurl = '/rest/users' 

export const loadUsers = (page = 0) => { 
    return (dispatch) => { 
    axios.get(userurl+"?page="+page) 
    .then(function(resp) { 
     dispatch(loadUsersOK(resp.data._embedded.users, resp.data.page)); 
    }) 
    .catch(function(error) { 
    ... 
    }) 
    }; 
} 

Komponent JSX

<span style={{marginRight:15, fontSize: 14, color: '#333'}}>{page.number*page.size+1}-{page.number*page.size+page.size} of {' '} {page.totalElements}</span> 
<FlatButton style={flatButtonStyle} icon={<NavigationChevronLeft/>} onTouchTap={this.prevPage} /> 
<FlatButton style={flatButtonStyle} icon={<NavigationChevronRight/>} onTouchTap={this.nextPage} /> 

składowe Rączki

prevPage() { 
    const { page } = this.props.users; 
    this.props.loadUsers(page.number - 1); 
    } 

    nextPage() { 
    const { page } = this.props.users; 
    this.props.loadUsers(page.number + 1); 
    } 

Połącz

const mapStateToProps = state => { 
    return { 
    users: state.users 
    } 
} 

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
    loadUsers: (page=0) => dispatch(loadUsers(page)) 
    } 
} 

const Wrapped = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(Users) 

TYLKO JEDNA AKCJA

export const loadUsersOK = (result, page) => ({ 
    type: LOAD_USERS_OK, 
    result, 
    page 
}) 

Może to pomaga.

+0

Po prostu brakuje części odbierającej ładunek. –