我的反应应用程序出了问题。我的问题是因为我的两个组件使用相同的reducer和action它们与它们在mapStateToProps中返回的数据冲突并覆盖前一个。有没有办法让他们从reducer返回不同的数据而不是覆盖?
我有这个组件通过api使用getMovieByGroup
操作获取数据,它使用api数据成功呈现所需视图,这里是代码:
class HomeBannerIndex extends React.Component {
constructor(props){
super(props);
}
componentWillMount(){
this.props.getMovieByGroup("popular");
}
renderFirstPopularMovie(){
if(this.props.data){
var headerBannerImage = {
backgroundImage: 'url(' + IMAGE_PATH + '/' + this.props.data.backdrop_path + ')'
};
return (
<div className={styles.homeBanner} style={headerBannerImage}>
<div className={styles.homeBannerText}>
<Col lg={10} md={10} sm={10} xs={12} className={util.center}>
<h1>{ this.props.data.original_title }</h1>
<h4>Release Date: { this.props.data.release_date }</h4>
</Col>
</div>
<div className={styles.overlay}></div>
</div>
);
}
}
render(){
return (
<Grid fluid={true}>
<Row>
<div className={styles.homeBannerGradient}>
{ this.renderFirstPopularMovie() }
</div>
</Row>
</Grid>
);
}
}
function mapStateToProps(state){
return {
data: state.film.data[9]
}
}
export default connect(mapStateToProps, { getMovieByGroup })(HomeBannerIndex);
我还有另一个组件也可以通过api获取相同的getMovieByGroup操作,但它有不同的参数:
class FilmItem extends React.Component {
constructor(props){
super(props);
}
componentWillMount(){
this.props.getMovieByGroup("latest");
}
render(){
return (
<div>
<Col lg={2} md={4} sm={6} xs={6}>
<div className={styles.filmBox}>
<Link to="/movies/2"><Image src="http://lorempixel.com/400/400/sports/" responsive /></Link>
</div>
</Col>
<Clearfix></Clearfix>
</div>
);
}
}
function mapStateToProps(state){
return {
data: state.film.data
}
}
export default connect(mapStateToProps, { getMovieByGroup })(FilmItem);
以下是我的行动中的代码,我在其中调度从API获取的数据:
export function getMovieByGroup(name){
return function(dispatch){
console.log(name);
return axios.get(`${API_URL}/movie/`+name,
{
params: {
api_key: API_KEY
}
}
)
.then(response => {
if(response.status === 200){
const result = response.data.results;
dispatch({ type: GET_FILM_SUCCESS, data: result, group: name });
}
})
.catch(error => {
const result = error.response;
console.log(result);
dispatch({ type: GET_FILM_FAILURE, data: result, group: name });
});
}
}
这里是减速器:
import { GET_FILM_SUCCESS,GET_FILM_FAILURE } from 'constants/FilmConstant.jsx';
const INITIAL_STATE = {
data: {}
};
export default (state = INITIAL_STATE, action) => {
switch(action.type) {
case GET_FILM_SUCCESS: {
return { ...state, data: action.data }
}
case GET_FILM_FAILURE: {
return { ...state, data: action.data }
}
default: return state;
}
}
答案 0 :(得分:0)
在您的reducer中,您可以从data
调度组和结果,而不是设置GET_FILM_SUCCESS
。
export function getMovieByGroup(name){
return function(dispatch){
return axios.get(`${API_URL}/movie/`+name,
{
params: {
api_key: API_KEY
}
}
)
.then(response => {
if(response.status === 200){
dispatch({ type: GET_FILM_SUCCESS, data: { group: name, results: response.data.results } });
}
})
.catch(error => {
dispatch({ type: GET_FILM_FAILURE, data: { group: name, results: error.response } });
});
}
}
然后将以下内容添加到reducer:
import { GET_FILM_SUCCESS,GET_FILM_FAILURE } from 'constants/FilmConstant.jsx';
const INITIAL_STATE = {
data: {},
error: {},
};
function processData(initialData, data) {
let updated = initialData;
updated[data.group] = data.results;
return updated;
}
export default (state = INITIAL_STATE, action) => {
switch(action.type) {
case GET_FILM_SUCCESS: {
return { ...state, data: processData(state.data, action.data) }
}
case GET_FILM_FAILURE: {
return { ...state, error: processData(state.data, action.data) }
}
default: return state;
}
}
我希望错误与数据分开处理。如果使用选择器,您将在以后获得更好的控制。