2017-02-16 34 views
0

我的反应应用程序出现问题。我的问题是,因为我的两个组件正在使用相同的reducers和action,它们与mapStateToProps中返回的数据发生冲突并覆盖前一个。有没有办法他们会从reducer返回不同的数据,而不是覆盖?在Reactjs中使用不同组件的同一个reducer

我有这样的组件,它通过使用getMovieByGroup行动成功地渲染与API数据所需要的视图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

在你减速,而不是设置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 } }); 
     }); 
    } 
} 

然后添加以下到您的减速机:

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; 
    } 
} 

我宁愿错误是从数据分开处理。如果您使用选择器,稍后您将拥有更好的控制权。

相关问题