我正在学习与Redux,React和React Router一起工作。 我面临这样的问题:
当我使用 Link 从“ /”重定向到“ / details / {id}”之类的URL时,我发现调用了错误的操作创建者。来自“ /”组件的动作创建者在“ / details / {id}”中称为该组件的独立行为。
但是,如果刷新页面,一切都会好起来的。要求采取正确的措施。
使用链接进行路由:<Link to={
/ details / $ {this.props.movie.id} }>
其他错误:如果我在此页面上按“返回”以返回到“ /”,则会收到错误消息,提示我的道具数据未定义。 例如,道具为空,并且未从componentDidMount()调用http请求的动作创建者(?)。
但是,如果我再次刷新页面,一切都会好起来的。
路由有什么问题??还是redux?
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<Routes />
</BrowserRouter>
</Provider>,
document.getElementById('root'));
const Routes = () => {
return <div>
<Route exact path="/" component={Main} />
<Route path="/details/:id" component={MovieDetailsContainer} />
</div>;
}
“ /”:
class MoviesDiscover extends Component {
componentDidMount() {
this.props.dicoverMovies();
}
render() {
...
}
}
const mapStateToProps = (state) => {
return {
items: state.movieItems,
hasErrored: state.movieHasErrored,
isLoading: state.movieIsLoading,
};
};
const mapDispatchToProps = (dispatch) => {
return {
dicoverMovies: (url) => dispatch(dicoverMovies(url))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(MoviesDiscover);
“细节/ {id}”:
class MovieDetailsContainer extends Component {
componentDidMount() {
var id = this.props.match.params.id;
this.props.getMovie(id); // called from MoviesDiscover instead of this, after routing
}
render() {
var id = this.props.match.params.id;
...
}
}
const mapStateToProps = (state) => {
return {
item: state.movieItems,
hasErrored: state.movieHasErrored,
isLoading: state.movieIsLoading,
};
};
const mapDispatchToProps = (dispatch) => {
return {
getMovie: (url) => dispatch(getMovieDetails(url))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(MovieDetailsContainer);
操作(两个要求相同-结果,错误和查找操作):
...
export function moviesDataSuccess(items) {
return {
type: MOVIES_RESULTS,
isLoading: false,
items: items
};
}
export function dicoverMovies() {
return (dispatch) => {
dispatch(moviesIsLoading(true));
API.get(URL_MOVIE_DISCOVER)
.then(response => {
dispatch(moviesIsLoading(false));
dispatch(moviesDataSuccess(response.data));
})
.catch(e => {
console.log(e);
dispatch(moviesHasErrored(true))
});
};
}
export function getMovieDetails(id) {
return (dispatch) => {
dispatch(moviesIsLoading(true));
API.get(URL_MOVIE_DETAILS(id))
.then(response => {
dispatch(moviesIsLoading(false));
dispatch(moviesDataSuccess(response.data));
})
.catch(e => {
console.log(e);
dispatch(moviesHasErrored(true))
});
};
}
减速器:
export function movieHasErrored(state = false, action) {
switch (action.type) {
case MOVIES_ERROR:
return action.hasErrored;
default:
return state;
}
}
export function movieIsLoading(state = false, action) {
switch (action.type) {
case MOVIES_LOADING:
return action.isLoading;
default:
return state;
}
}
export function movieItems(state = {}, action) {
switch (action.type) {
case MOVIES_RESULTS:
return action.items;
default:
return state;
}
}
const rootReducer = combineReducers({
movieHasErrored,
movieIsLoading,
movieItems
});
我对所有建议都很满意。谢谢。
答案 0 :(得分:1)
反应路由器首先匹配关闭URL,我认为问题在于组件的顺序。 我建议您像这样订购它们,并且应该可以解决:
const Routes = () => {
return <div>
<Route path="/details/:id" component={MovieDetailsContainer} />
<Route exact path="/" component={Main} />
</div>;
}
React Router还有一个用于在URL之间切换的组件,如果URL模棱两可,您可以利用它:
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
...
<Switch>
<Route path="/about" component={About} />
<Route path="/company" component={Company} />
<Route path="/:user" component={User} />
</Switch>
PS:抱歉,如果这不是您要查找的答案,我只是想发表评论,而不是发布此答案,我只是还没有直接评论的声誉:| >
答案 1 :(得分:0)
我的错误是在其他地方。
问题是,我使用相同的操作类型来获取列表结果和详细信息。
当我打开一个页面查看详细结果时,我从上一页获得了带有列表结果的道具(因为它们使用相同的动作类型)。在我的“详细信息”组件获取新数据之前。
我的代码无法使用错误的数据进行渲染。