我正在使用react-router和react-router-redux来处理我页面上的导航。我需要以编程方式在组件内部更改我的URL。我试图使用这个方法:history.push来实现这个但是这个方法只是改变了url和与这个url相关联的组件没有更新。这个应用程序是一个简单的分页列表,所以当我切换到下一页时,url正在更改例如/ posts / 1到/ posts / 2但是视图没有更新。我认为这应该是这样的:
这可能不是最好的方法,所以我会很高兴提示 链接是硬编码的,特别是第一个参数 我的源代码:
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>
);
}
}
减速器/ 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
减速器/ 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)));
}
}
答案 0 :(得分:2)
由于您没有更改组件树,因此不会再次装入ObjectList组件。它仍然是
<Home>
<Results>
<ObjectList />
</Results>
</Home>
只有当您转到不同的路径并安装不同的根组件以便整个树都会改变时,它才会被重新安装。但你只是传递不同的道具。你需要使用
componentWillReceiveProps(nextProps) {
this.props.fetchObjects(nextProps.params.pageNum);
}