【问题标题】:How to map multiple states to props by using Redux in React?如何在 React 中使用 Redux 将多个状态映射到 props?
【发布时间】:2018-10-13 11:37:57
【问题描述】:

我是一个反应新手,我试图从几个动作中获取数据 - 在一个组件中,所以我的目标是这样做:

假设我有一个组件名称 在里面我想这样做:

componentWillMount() {
    this.props.fetchGenres();
    this.props.fetchMovies();
}

在出口区:

AllMovies.propTypes = {
  fetchMovies: propTypes.func.isRequired,
  fetchGenres: propTypes.func.isRequired,
  genres: propTypes.array.isRequired,
  movies: propTypes.array.isRequired
};
const mapStateToProps = state => ({
  genres: state.genres,
  movies: state.movies.items,
  newMovie: state.movies.item,
  editedMovie: state.movies.item
});

export default connect(
  mapStateToProps,
  { fetchMovies, fetchGenres }
)(AllMovies);

如果我在“导出默认连接”中仅使用一个地图,我不会收到任何错误 - 但是当我将另一个地图添加到连接对象时 - 我会收到错误

所以我的问题是 - 这是将多个状态映射到道具的正确方法吗?

【问题讨论】:

  • 另一个map 是什么意思?在 redux 中只有一种状态。你为什么需要另一个mapStateToProps
  • 一个 mapStateToProps 可以从 redux 存储中获取所有状态,并通过 connect 方法将它们作为 props 可用,那么为什么还需要另一个 mapStateToProps 呢?
  • 如果您想传递函数,请将其添加到 mapStateToProps 中,而不是将其作为调度的一部分传递。尝试在 mapStateToProps 中添加 fetchMovies: fetchMovies, fetchGenres: fetchGenres

标签: reactjs redux


【解决方案1】:

我看不出你的代码有什么问题,但也许你在将动作创建者传递给连接的第二个参数时没有导入它们?它会显示类似 -ReferenceError: fetchMovies is not defined 的内容。如果是这样,这是因为您尝试将 {fetchMovies, fetchGenres} 传递给 connect 函数而不是 componentWillMount() 中的代码。

// Import statements
import { fetchMovies, fetchGenres } from '/path/to/actionCreators';


// Your react component somewhere here.


const mapStateToProps = state => {
    // This is the longhand of what you did
    return {
        genres: state.genres,
        movies: state.movies.items,
        newMovie: state.movies.item,
        editedMovie: state.movies.item
    };
};

/**
 * It's generally more clear to have mapDispatchToProps 
 * as a variable instead of passing the object directly 
 * to the connect. It's not wrong though. Make sure these
 * are imported.
 */

const mapDispatchToProps = {
    fetchMovies
    fetchGenres
};

export default connect(mapStateToProps, mapDispatchToProps)

【讨论】:

    【解决方案2】:

    我总是使用“bindActionCreators”来绑定 redux 动作。所以你的代码会是这样的:

    import { bindActionCreators } from 'redux';
    import * as genreActionCreators from '@redux/actions/genre-actions'; // Path to the file containing the redux action fetchGenres().
    import * as movieActionCreators from '@redux/actions/movie-actions'; // Path to the file containing the redux action fetchMovies().
    
    class AllMovies extends Component {
    
      componentWillMount() {
        this.props.actions.genres.fetchGenres();
        this.props.actions.movies.fetchMovies();
      }
    
      // Rest of the component code
    
    }
    
    AllMovies.propTypes = {
      fetchMovies: propTypes.func.isRequired,
      fetchGenres: propTypes.func.isRequired,
      genres: propTypes.array.isRequired,
      movies: propTypes.array.isRequired
    };
    
    // Subscribing the component to redux store changes.
    function mapStateToProps(state) {
      return {
        genres: state.genres,
        movies: state.movies.items,
        newMovie: state.movies.item,
        editedMovie: state.movies.item
      };
    }
    
    // Enables the component to dispatch actions
    function mapDispatchToProps(dispatch) {
      return {
        actions: {
          movies: bindActionCreators(movieActionCreators, dispatch),
          genres: bindActionCreators(genreActionCreators, dispatch),
        },
      };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(AllMovies);
    

    希望这会有所帮助。干杯!

    【讨论】:

      猜你喜欢
      • 2016-04-13
      • 1970-01-01
      • 2018-09-13
      • 2018-10-25
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 2017-11-07
      • 2016-12-03
      相关资源
      最近更新 更多