我有一个React + Redux应用程序,该应用程序可以在供稿列表页面中为每个用户获取供稿,并能够在新页面中查看特定供稿项的更多详细信息(我将在下面的代码示例中进行解释)。有一个API可以获取供稿列表,但没有API可以获取特定供稿项目的详细信息。如何将数据从Feed列表页面传递到Feed详细信息页面?我将如何处理Feed详细信息页面的重新加载,或者如何处理用户可以为Feed详细信息页面添加书签并在以后访问的场景?
我的代码如下:
app.js
import React from 'react';
import {
Route,
Switch
} from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router'
import Home from './homeComponent';
import Login from './loginComponent';
import FeedListing from './feedListingComponent';
import FeedDetails from './feedDetailsComponent';
import NoMatch from './NoMatchComponent';
const App = ({ history }) => {
return (
<ConnectedRouter history={history}>
<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/feed/:profileId" component={FeedListing} />
<Route path="/feed_details/:feedId" component={FeedDetails} />
... more routes
<Route component={NoMatch} />
</Switch>
</ConnectedRouter>
);
};
export default App;
feedListingComponent.js
import React, {Component} from 'react'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as feedActions from '../actions/feedActions';
class FeedListingComponent extends Component {
constructor(props) {
super();
}
componentDidMount() {
const { profileId } = this.props.match.params;
this.props.actions.getFeed(profileId); // Calls API to get feed for feed listing and contains all the data that would be required for the feed details in each feed item
}
render() {
return (
<div>
... code that loops through the getFeed response starts here
<a href="/feed_details/{feedId}">Go to details</a>
... code that loops through the getFeed response ends here
</div>
)
}
}
function mapStateToProps(state) {
return {
feed: state.feed.get('feed')
}
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(feedActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(FeedListingComponent);
feedDetailsComponent.js
import React, {Component} from 'react'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as feedActions from '../actions/feedActions';
class FeedDetailsComponent extends Component {
constructor(props) {
super();
}
componentDidMount() {
... some code here
}
render() {
return (
<div>
... need to show the feed details here
</div>
)
}
}
function mapStateToProps(state) {
return {
... some code here
}
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(feedActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(FeedDetailsComponent);
我也在考虑调用API以在详细信息页面中获取供稿列表的供稿,这意味着我还需要将:profileId传递到供稿详细信息路由,以使供稿列表API能够正常工作:
<a href="/feed_details/{feedId}/{profileId}">Go to details</a>
然后我可以像这样通过feedId过滤响应:
const feedItem = feed.filter(function(feedItem){
return feedItem.feedId == feedId;
});
但是,鉴于饲料可能包含成千上万种饲料,这根本不是一个最佳解决方案。
谁能建议一种更好,更优化的方式来处理我提到的所有情况。
更新:同时添加我的操作和化简代码。
feedActions.js
import * as actionTypes from './actionTypes';
import feedApi from '../api/feedApi';
export function getFeed(profileId) {
return function(dispatch) {
return feedApi.getFeed(profileId).then(response => {
dispatch(getFeedSuccess(response.data));
}).catch(error => {
throw(error);
});
};
}
export function getFeedSuccess(response) {
return { type: actionTypes.FEED, feed : response }
}
feedReducer.js
import Immutable from 'immutable';
import * as actionTypes from '../actions/actionTypes';
const initialState = Immutable.fromJS({
feed: {}
});
export default function feedReducer(state = initialState, action) {
switch(action.type) {
case actionTypes.FEED:
return state.setIn(['feed'], action.feed)
default:
return state;
}
}
getFeed响应
[
{
feedId: 1,
feedTitle: "Lorem ipsum",
feedDescription: "Lorem ipsum"
},
{
feedId: 2,
feedTitle: "Lorem ipsum",
feedDescription: "Lorem ipsum"
},
{
feedId: 3,
feedTitle: "Lorem ipsum",
feedDescription: "Lorem ipsum"
},
... and so on
]
答案 0 :(得分:0)
不幸的是,如果不仔细检查每一项,就无法在数组中找到特定元素,这仅仅是数据结构的局限。
但是,我假设feedListing组件将不会显示数百万个项目的列表。您可能会希望在那里进行某种分页,对吗?
在这种情况下,您可以跟踪显示哪个页面,并从也存储在商店中的主数组中切出一个较小的数组。当用户转到下一页时,一个操作会从主数组中切出正确的部分并更新存储。然后,当用户选择这些项目之一并转到详细信息页面时,您只需过滤较小的数组即可找到正确的项目,因为您知道所选项目位于正确的页面上。
编辑:再次查看此内容,我个人将其结构化的方法是将其全部放到一页上,并在用户选择可见项时有条件地渲染详细信息组件。
class FeedListingComponent extends Component {
constructor(props) {
super();
this.state = {
selectedItem: null,
}
}
componentDidMount() {
const { profileId } = this.props.match.params;
this.props.actions.getFeed(profileId); // Calls API to get
feed for feed listing and contains all the data that would be required
for the feed details in each feed item
}
displayDetails(item) {
this.setState({
selectedItem: item
})
}
render() {
if(this.state.selectedItem) {
return (
<FeedDetailsComponent
selectedItem={this.state.selectedItem}
/>
);
return (
{this.props.feed.map(feedItem => (
<ListItemComponent
onClick={() => this.displayDetails(feedItem)}
/>
}
);
}
}
希望这是有道理的。您将需要在详细信息页面上使用某种“后退”按钮来将selectedItem设置为null,以便列表显示返回