【问题标题】:React Redux + Saga Image CarouselReact Redux + Saga 图像轮播
【发布时间】:2017-05-22 11:10:40
【问题描述】:

我正在构建一个包含主图像和缩略图列表的轮播。

有 prev 和 next 按钮允许用户浏览图像列表。

到目前为止,这是我的代码:

import styles from './carousel.css';
import cn from '../../../utils/classname';
import actions from '../../../actions';

import Magnified from '../../../svg/icons/ui/magnified_glass';
import ArrowRight from '../../../svg/icons/ui/arrow_right';
import ArrowLeft from '../../../svg/icons/ui/arrow_left';

const Carousel = ({ dispatch, selectedCaravan }) =>
  <div className={cn(styles.carouselWrap)}>
        <div className={cn(styles.carouselFeatWrap)}>
            <a href="#" className={cn(styles.carouselExpand)} onClick={() => dispatch({ type: actions.CAROUSEL_EXPAND })}>
                <Magnified />
            </a>
            <ul className={cn(styles.carousel)}>
        {selectedCaravan.images && selectedCaravan.images.map((image, i) => {
          return <li key={i}>
            <img src={image} />
          </li>;
        })}
            </ul>   
        </div>
        <div className={cn(styles.carouselThumbNavWrap)}>
            <ul className={cn(styles.carouselThumbnails)}>
        {selectedCaravan.images && selectedCaravan.images.map((image, i) => {
          return <li key={i} onClick={() => dispatch ({ type: actions.CAROUSE_GO_TO })}>
            <img src={image} />
          </li>;
        })}
            </ul>
            <div className={cn(styles.carouselNavigation)}>
                <a href="#" className={cn(styles.carouselNavPrev)} onClick={() => dispatch({ type: actions.CAROUSEL_PREV })}>
                    <ArrowLeft />
                </a>
                <a href="#" className={cn(styles.carouselNavNext)} onClick={() => dispatch({ type: actions.CAROUSEL_NEXT })}>
                    <ArrowRight />
                </a>
            </div>
        </div>
  </div>;

export default Carousel;

我有诸如CAROUSEL_NEXTCAROUSEL_PREV 之类的操作。我正在我的 sagas 中监听这些操作,我对此的想法是我需要更新选定的索引并以某种方式将主图像更新为用户选择的任何一个。

到目前为止,我的传奇是这样的:

const carouselPrev = function* (payload) {

  const updateSelectedIndex = payload.updateSelectedIndex;

  if (updateSelectedIndex) {
    return false;
  }

  yield put({ type: actions.CAROUSEL_PREV, payload: updateSelectedIndex });

};

我不确定当用户选择新图像时如何更新所选索引,以及如何为轮播设置动画或实质上制作轮播幻灯片。

【问题讨论】:

    标签: reactjs react-redux redux-saga


    【解决方案1】:

    我认为你根本不需要这个传奇。

    您只需定义减速器的操作

    // Action creators
    const selectNext = () => ({
      type: 'SELECT_NEXT',
    })
    
    const selectPrev = () => ({
      type: 'SELECT_PREV',
    })
    
    const selectById = (id) => ({
      type: 'SELECT_BY_ID',
      payload: id,
    })
    
    // Reducer
    
    const initial = {
      selectedImageId: 0,
      /* other state */
    }
    
    function reducer(state = initial, action) {
      switch(action.type) {
        case 'SELECT_NEXT':
          return {
            ...state,
            selectedImageId: state.selectedImageId + 1,
          }
        case 'SELECT_PREV':
          return {
            ...state,
            selectedImageId: state.selectedImageId - 1,
          }
        case 'SELECT_BY_ID':
          return {
            ...state,
            selectedImageId: action.payload,
          }
        default:
          return state
      }
    }

    在此之后,您传递来自 react-redux 的回调

    const Component = ({ selectedImageId, onNext, onPrev, onSelect }) => (
      <div>
        <CarouselMainImage 
          id={selectedImageId} // this component will know which image to display based on this id
        />
        {/* ... */}
        <CarouselImages
          onClick={onSelect}
        />
        {/* ... */}
        <PrevBtn
          onClick={onPrev}
        />
        <NextBtn
          onClick={onNext}
        />
        {/* ... */}
      </div>
    )
    
    const mapStateToProps = state => ({
      selectedImageId: state.selectedImageId
    })
    
    const mapDispatchToProps = dispatch =>
      // use action creators here
      bindActionCreators({
        onNext: onSelectNext,
        onPrev: onSelectPrev,
        onSelect: onSelectById,
      }, dispatch)
    
    const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps)

    对于过渡,您可以使用:https://github.com/reactjs/react-transition-group

    【讨论】:

    • 感谢@notgiorgi。我想知道在第一个 sn-p 代码中,这些动作创建者会去哪里,因为我已经设置了动作来监听点击?
    • 动作创建者只是帮助轻松分发动作,而不是每次都手动编写它们
    • 好的,谢谢,我只是想弄清楚如何将它应用到我的项目中,如果有意义的话,哪些代码应该放在哪里。
    • 为了帮助解决这个问题,项目正在使用 Ramda 并像上面一样递增状态
    • 好吧,如果你在谈论文件系统方面的问题,你应该有:actions.js 用于动作创建者,reducer.js 用于减速器,constants.js 用于动作类型(这不是一个好习惯传递字符串)。您可能还拥有selectors.js 并将state.selectedImageId 移动到那里
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2019-02-21
    • 2016-10-27
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    相关资源
    最近更新 更多