2016-06-25 22 views
1

Ich benutze react-router und react-router-redux, um Navigation auf meiner Seite zu behandeln. Ich muss meine URL programmgesteuert in der Komponente ändern. Ich habe versucht, diese Methode zu verwenden: history.push, um dies zu erreichen, aber diese Methode ist nur ändern die URL und Komponente mit dieser URL verknüpft ist nicht aktualisiert. Diese App ist eine einfache Liste mit Paginierung, also, wenn ich zur nächsten Seite wechseln URL ändert sich zum Beispiel/posts/1 nach/posts/2, aber die Ansicht wird nicht aktualisiert. Ich denke, das sollte so funktionieren:Wie navigiere ich mit reactjs und redux

  1. Benutzer klicken Paginierung Artikel und klicken Sie auf Handler Seitennummer als Argument
  2. Innenrasterung Handler i rufen history.push (/ Beiträge/[Seite]) genannt wird, vorbei. Ich konnte Verwendung Link-Komponente, aber ich möchte in der Lage sein, etwas zu tun, wenn der Benutzer klicken Paginierung Artikel
  3. Ich erwarte, dass meine Object Komponente wieder montiert werden und componentDidMount wird

Dies genannt wird wahrscheinlich nicht die beste aproach so werde ich für Tipps Links sind fest einprogrammiert besonders erstes Argument Mein Quellcode greatfull:

Client.js

import React from "react"; 
import ReactDOM from "react-dom"; 
import {Router, Route, IndexRoute, browserHistory} from "react-router"; 
import Results from "./views/Results"; 
import Home from "./views/Home"; 
import App from './components/App' 
import { Provider } from 'react-redux'; 
import store, { history } from './store'; 


const app = document.getElementById('app'); 

ReactDOM.render(
    <Provider store={store}> 
    <Router history={history}> 
     <Route path="/" component={App}> 
     <IndexRoute component={Home} /> 
     <Route path="/:category/:cityId/:pageNum" component={Results}></Route> 
    </Route> 
    </Router> 
    </Provider>, 
    app 
); 

store.js

import { createStore, compose, applyMiddleware } from 'redux' 
import { syncHistoryWithStore } from 'react-router-redux' 
import thunkMiddleware from 'redux-thunk' 
import { browserHistory } from 'react-router' 
import rootReducer from './reducers/index' 
import createLogger from 'redux-logger' 
import categories from './data/categories' 

const loggerMiddleware = createLogger() 

const defaultState = { 
    categories, 
    resultsList: { 
     objects: [], 
     counters: [], 
     isFetching: false 
    } 
}; 

const store = createStore(
    rootReducer, 
    defaultState, 
    compose (
    applyMiddleware(
     thunkMiddleware, 
     loggerMiddleware 
    ), 
    window.devToolsExtension ? window.devToolsExtension() : f => f 
) 
); 
export const history = syncHistoryWithStore(browserHistory, store) 
export default store 

ObjectList.js

import React from "react"; 
import ObjectItem from "../components/ObjectItem" 
import Loader from "../components/Loader" 
import fetchObjects from "../actions/actionCreators"; 
import switchUrl from "../actions/actionCreators"; 
import PaginationPanel from "../components/PaginationPanel" 
import classNames from 'classnames' 
import { push } from 'react-router-redux'; 
import { browserHistory } from 'react-router' 
import store, { history } from '../store'; 


export default class ObjectList extends React.Component { 
    static defaultProps = { 
     objectsPerPage: 20, 
     objectContainerClassName: 'object_list_items' 
    } 

    constructor(props) { 
     super(props); 
    } 

    componentDidMount() { 
    this.props.fetchObjects(this.props.params.pageNum); 
    } 

    paginateHandler(page) { 
     this.props.history.push('/hotele/1/'+page) 
    } 

    render() { 
    const { resultsList } = this.props 

    if(resultsList.items.length > 0) { 
     const ObjectComponents = resultsList.items.map((item) => { 
      return <ObjectItem key={item.post_id} {...item}/>; 
     }); 

     const paginationComponent = 
     <PaginationPanel 
      {...this.props} 
      pageNum={Math.ceil(resultsList.counters.allPosts/this.props.objectsPerPage)} 
      pageClickedHandler={this.paginateHandler.bind(this)} 
      currentPage={parseInt(this.props.params.pageNum)} 
     /> 

     return (
     <div className="object-lists"> 
      <div className={this.props.objectContainerClassName}> 
       <div>{ObjectComponents}</div> 
      </div> 
      {paginationComponent} 
     </div> 
    ) 
    } 
    else if(!resultsList.isFetching || resultsList.items.length === 0) { 
     return <Loader />; 
    } 
    } 
} 

Home.js

import React from "react" 
import { Link } from "react-router" 


const Home = React.createClass({ 
    render() { 
    return (
     <div> 
      Strona główna <br /> 
     <Link to={`/hotele/1/1`}>Lista wyszukiwania</Link> 
     </div> 
    ) 
    } 
}) 

export default Home 

Results.js

import React from "react"; 
import ObjectList from "../components/ObjectList" 
import CategoryTabs from "../components/CategoryTabs" 
import fetchObjects from "../actions/actionCreators" 


export default class Results extends React.Component{ 
    constructor(props) { 
    super(props); 
    } 

    render() { 
     return (
      <div> 
       <CategoryTabs { ...this.props } /> 
       <ObjectList { ...this.props } /> 
      </div> 
    ); 
    } 
} 

Reduzierstücke/index.js

import { combineReducers } from 'redux' 
import { routerReducer } from 'react-router-redux' 

import objects from './objects' 
import categories from './categories' 

const rootReducer = combineReducers({objects, categories, routing: routerReducer}) 

export default rootReducer 

Reduzierstücke/objects.js

function objects(state = { 
    isFetching: false, 
    items: [], 
    counters: [] 
}, action) { 
    switch (action.type) { 
    case 'RECEIVE_OBJECTS': 
     return Object.assign({}, state, { 
     isFetching: false, 
     items: action.objects.posts, 
     counters: action.objects.counters 
     }) 
    default: 
     return state; 
    } 
} 

export default objects 

app.js

import { bindActionCreators } from 'redux' 
import { connect } from 'react-redux' 
import * as actionCreators from '../actions/actionCreators'; 
import Main from '../components/Main'; 


function mapStateToProps(state) { 
    return { 
    resultsList: state.objects, 
    categories: state.categories 
    } 
} 

function mapDispatchToProps(dispatch) { 
    return bindActionCreators(actionCreators, dispatch); 
} 

const App = connect(mapStateToProps, mapDispatchToProps)(Main); 

export default App; 

actionCreators.js

import fetch from 'isomorphic-fetch' 
import { push } from 'react-router-redux'; 


function receiveObjects(objects, json) { 
    return { 
    type: 'RECEIVE_OBJECTS', 
    objects 
    } 
} 

function requestObject(pageNum) { 
    return { 
    type: 'REQUEST_OBJECTS', 
    pageNum 
    } 
} 

export function fetchObjects(pageNum) { 
    return dispatch => { 
     dispatch(requestObject(pageNum)); 

     let url = 'http://localhost:8080/posts?city=986283&type=hotel&page='+pageNum; 

     return fetch(url) 
     .then(response => response.json()) 
     .then(json => dispatch(receiveObjects(json))); 
    } 
} 

Antwort

2

Object Komponente nicht angebracht werden wieder, weil du die Compo nicht veränderst nents Baum. Es ist noch

<Home> 
    <Results> 
     <ObjectList /> 
    </Results> 
</Home> 

wird es nur wieder montiert werden, wenn Sie auf einen anderen Weg zu gehen und verschiedene Wurzelkomponenten montieren, so der ganze Baum ändern würde. Aber du gibst einfach verschiedene Requisiten. Sie müssen verwenden

componentWillReceiveProps(nextProps) { 
    this.props.fetchObjects(nextProps.params.pageNum); 
} 
+0

seine Arbeit jetzt vielen Dank! :) –

Verwandte Themen