【问题标题】:Trying to convert react-bootstrap carousel to es6 and redux试图将 react-bootstrap 轮播转换为 es6 和 redux
【发布时间】:2016-10-27 11:39:06
【问题描述】:

我已从此处获取受控轮播的示例代码:https://react-bootstrap.github.io/components.html#media-content

我正在尝试通过我的 redux 设置使其在 es6 中工作,但是唉!尽管我付出了所有崇高的努力,但我仍然收到以下错误:

SlideShow.js?d20f:20 Uncaught TypeError: Cannot read property 'direction' of undefined

  1. 我在以下代码中没有绑定/做错什么?
  2. 我可以在我的哑组件中处理这样的状态吗?
  3. 为什么忘恩负义的英国人为什么要离开我们? ;((抱歉划伤)

这是我的哑组件(component/sldeshow.js):

 import React, { Component, PropTypes } from 'react'
import { List } from 'immutable'
import { Link } from 'react-router'
import { Carousel } from 'react-bootstrap'

class Slides extends Component {

constructor(props) {
    super(props)
    this.state = {
      index: 0,
      direction: null
    }

    // Bind callback methods to make `this` the correct context.
    this.handleSelect = this.handleSelect.bind(this)

  }

  handleSelect(selectedIndex, e) {
    alert('selected=' + selectedIndex + ', direction=' + e.direction)
    this.setState({
      index: selectedIndex,
      direction: e.direction
    })
  }

  render() {
    return (
      <div>
          {
            //this.props.slides
            this.props.slides.map((s)=> 
            {
              let id = s.get('id')
              let title = s.get('title')
              let image = s.get('image')
              let alt = s.get('alt')
              let caption = s.get('caption')
              return (

                <Carousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect} key={id}>
                  <Carousel.Item>
                    <img width={640} height={480} alt="640x480" src={image} alt={alt}/>
                    <Carousel.Caption>
                      <h3>{title}</h3>
                      <p>{caption}</p>
                    </Carousel.Caption>
                  </Carousel.Item>
                  <Carousel.Item>
                    <img width={640} height={480} alt="640x480" src={image} alt={alt}/>
                    <Carousel.Caption>
                      <h3>{title}</h3>
                      <p>{caption}</p>
                    </Carousel.Caption>
                  </Carousel.Item>
                  <Carousel.Item>
                    <img width={640} height={480} alt="640x480" src={image} alt={alt}/>
                    <Carousel.Caption>
                      <h3>{title}</h3>
                      <p>{caption}</p>
                    </Carousel.Caption>
                  </Carousel.Item>
                </Carousel>
                   )
          })
        }
      </div>
    )
  }
}

Slides.propTypes = {

  slides: PropTypes.instanceOf(List).isRequired
}


export default Slides

智能容器:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router'

import Slides from 'components/SlideShow'
import { getInitalSlides } from 'actions/SlidesActions'


class Home extends Component {

static fetchData({ store }) {
        return store.dispatch(getInitalSlides())
    }

    componentDidMount() {
        this.props.getInitalSlides()
  }

  render() {
    return (
      <div className="Home">
        <h1>Home Page</h1>
        <Slides slides={this.props.slides} />
        <div><Link to="/question">to question</Link></div>
        <div><Link to="/posts">to posts</Link></div>
      </div>
    )
  }
}

function mapStateToProps (state) {
  return { slides: state.slides }
}

export { Home }
export default connect(mapStateToProps, { getInitalSlides })(Home)

和示例轮播原代码:

const ControlledCarousel = React.createClass({
  getInitialState() {
    return {
      index: 0,
      direction: null
    };
  },

  handleSelect(selectedIndex, e) {
    alert('selected=' + selectedIndex + ', direction=' + e.direction);
    this.setState({
      index: selectedIndex,
      direction: e.direction
    });
  },

  render() {
    return (
      <Carousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
        <Carousel.Item>
          <img width={900} height={500} alt="900x500" src="/assets/carousel.png"/>
          <Carousel.Caption>
            <h3>First slide label</h3>
            <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
          </Carousel.Caption>
        </Carousel.Item>
        <Carousel.Item>
          <img width={900} height={500} alt="900x500" src="/assets/carousel.png"/>
          <Carousel.Caption>
            <h3>Second slide label</h3>
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
          </Carousel.Caption>
        </Carousel.Item>
        <Carousel.Item>
          <img width={900} height={500} alt="900x500" src="/assets/carousel.png"/>
          <Carousel.Caption>
            <h3>Third slide label</h3>
            <p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
          </Carousel.Caption>
        </Carousel.Item>
      </Carousel>
    );
  }
});

附言 我正在从 api 中提取幻灯片

【问题讨论】:

    标签: javascript reactjs ecmascript-6 redux react-bootstrap


    【解决方案1】:

    在轮播组件中尝试onSelect={(i,e)=&gt;this.handleSelect(i,e)}

    【讨论】:

      【解决方案2】:

      为了将来的兴趣,这里是我的带有 redux 的受控轮播代码。

      注意如果你没有定义activeIndex、direction和onSelect 作为组件上的道具,幻灯片将起作用(包括上一个和下一个按钮),但您的应用状态不会改变,因为您实际上并没有自己处理动作,而是由 react-bootstrap 库在本地完成。

      作为一个初学者,我在将这些道具(activeIndex 等)从容器传递到组件时遇到了问题,但经过更多阅读后,它变得更加清晰。

      关键是要明白容器上的this.state和this.props会在组件上可用。见以下代码:

      容器名称.js:

      import React, { Component } from 'react'
      import { connect } from 'react-redux'
      import { Link } from 'react-router'
      import store from 'store/configureStore'
      import Slides from 'components/SlideShow'
      import { getInitalSlides, handleSelect } from 'actions/SlidesActions'
      
      class Home extends Component {
      
      constructor(props) {
          super(props)
          this.state = {
              index: null,
              direction: null
          }
          this.handleSelect = this.handleSelect.bind(this)    
      
      static fetchData({ store }) {
              return store.dispatch(getInitalSlides())
          }
      
          componentDidMount() {
              this.props.getInitalSlides()
          }
      
      handleSelect(selectedIndex, e) {
              //alert(e)
              this.props.handleSelect(selectedIndex, e)
          }
      
        render() {
          return (
            <div className="Home">
              <h1>Home Page</h1>
              <Slides 
              slides={this.props.slides}   
              getInitialState={this.state.index} 
              getInitialStateD={this.state.direction}
              slidesControl={this.handleSelect}
              />
              <div><Link to="/question">to question</Link></div>
              <div><Link to="/posts">to posts</Link></div>
            </div>
          )
        }
      }
      
      function mapStateToProps (state) {
        const { slides, handleSelect } = state
      
        return { slides: state.slides, onSelect: state.handleSelect } 
      }
      
      export { Home }
      export default connect(mapStateToProps { getInitalSlides, handleSelect})(Home)
      

      组件名称.js:

      import React, { Component, PropTypes } from 'react'
      import { List } from 'immutable'
      import { Link } from 'react-router'
      import { Carousel } from 'react-bootstrap'
      
      class Slides extends Component {
      
      //A helper method to feed the list into the render. Prob. could be done much better.
      
      listSlides(s){
      
          let id = s.get('id')
          let title = s.get('title')
          let image = s.get('image')
          let alt = s.get('alt')
          let caption = s.get('caption')
          return(
      
                          <Carousel.Item key={id} >
                          <img width={900} height={500} alt={s.get('alt')} src={image} alt={alt}/>
                          <Carousel.Caption>
                            <h3>{title}</h3>
                            <p>{caption}</p>
                          </Carousel.Caption>
                        </Carousel.Item>
      
                    ) 
      }
      
        render() {
      
          return (
            <Carousel 
            //The name of the method must match the name of the prop on the container parent
            activeIndex={this.props.getInitialState} 
            direction={this.props.getInitialStateD} // <-- Here's a good example
            onSelect={(selectedIndex,e)=>this.props.handleSelect(selectedIndex,e)}
            >
            {
            this.props.slides.map(s=>this.listSlides(s))
          }
          </Carousel>)
        }
      }
      
      Slides.propTypes = {
      
        slides: PropTypes.instanceOf(List).isRequired,
        handleSelect: PropTypes.func.isRequired
      }
      
      
      export default Slides
      

      动作名称.js:

      export const HANDLE_SELECT = Symbol('HANDLE_SELECT')
      export function handleSelect(selectedIndex, e) {
          //alert('selected=' + selectedIndex + ', direction=' + e.direction)
      
          return {
              index: selectedIndex,
              direction: e.direction,
              type: HANDLE_SELECT
          }
      }
      

      reducer-name.js:

      import * as ActionType from 'actions/SlidesActions'
      import Immutable from 'immutable'
      
      let defaultState = Immutable.fromJS({
      
          index: null,
        direction: null
      })
      
      function handleSelect (state=defaultState, action) {
        switch(action.type) {
      
          case ActionType.HANDLE_SELECT:
            //alert(action.type + " " + ActionType.HANDLE_SELECT)
            return(state.merge({ updatedHandleSelect: action }))
      
          default:
            return state
        }
      }
      
      export default handleSelect //For the root reducer
      

      最后,在最新的 react-bootstrap 版本中,存在一个错误(正在修复),该错误将在受控轮播上抛出“未捕获的类型错误:无法读取未定义的属性持久性”。

      这是github issue,您可以回滚一个版本,直到它被修复

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-22
        • 1970-01-01
        • 2012-10-09
        • 1970-01-01
        • 2023-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多