2017-05-22 10 views
-2

Ich habe eine reactjs Komponente mit Redux, die asynchron Requisiten an Kind-Komponente übergibt.ReactJS übergeben Requisiten an Kind über Redux Ajax

In Kind-Komponente Ich versuche, die Daten in ComponentDidMount zu fangen, aber irgendwie funktioniert auch nicht, aber die untergeordnete Komponente wird gerendert.

Dies ist mein Stammkomponente

import React from 'react'; 
import {connect} from 'react-redux'; 
import {bindActionCreators} from 'redux'; 
import * as slidesActions from '../../actions/slidesActions'; 
import Slider from '../Partials/Slider' 
import _ from 'underscore'; 


class HomePage extends React.Component { 

    constructor(props) { 
     super(props); 
    } 

    componentDidMount() { 
     this.props.actions.getSlides() 
    } 

    componentWillMount() { 
     const {slides} = this.props; 
    } 

    render() { 
     const {slides} = this.props; 

     return (
      <div className="homePage"> 
       <Slider columns={1} slides={slides} /> 
      </div> 
     ); 
    } 
} 

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

function mapDispatchToProps(dispatch) { 
    return { 
     actions: bindActionCreators(slidesActions, dispatch) 
    }; 
} 


export default connect(mapStateToProps, mapDispatchToProps)(HomePage); 

hier kommt mein Kind Komponente, wo ich versuche, übergeben Dias Requisiten zu bekommen, aber ist leer

import React from 'react'; 
import _ from 'underscore'; 
import Hammer from 'hammerjs'; 


class Slider extends React.Component { 

    constructor(props) { 
     super(props) 
     this.updatePosition = this.updatePosition.bind(this); 
     this.next = this.next.bind(this); 
     this.prev = this.prev.bind(this); 

     this.state = { 
      images: [], 
      slidesLength: null, 
      currentPosition: 0, 
      slideTransform: 0, 
      interval: null 
     }; 
    } 

    next() { 
     const currentPosition = this.updatePosition(this.state.currentPosition - 10); 
     this.setState({ currentPosition }); 

    } 

    prev() { 
     //TODO: work on logic 
     if(this.state.currentPosition !== 0) { 
      const currentPosition = this.updatePosition(this.state.currentPosition + 10); 
      this.setState({currentPosition}); 
     } 
    } 


    componentDidMount() { 
     //here I try set a state variable on slides 
     let {slides} = this.props 
     let slidesLength = slides.length 
     this.setState({slidesLength}) 

     this.hammer = Hammer(this._slider) 
     this.hammer.on('swipeleft', this.next); 
     this.hammer.on('swiperight', this.prev); 
    } 

    componentWillUnmount() { 
     this.hammer.off('swipeleft', this.next) 
     this.hammer.off('swiperight', this.prev) 
    } 

    updatePosition(nextPosition) { 
     const { visibleItems, currentPosition } = this.state; 
     return nextPosition; 
    } 

    render() { 
     let {slides, columns} = this.props 
     let {currentPosition} = this.state 
     let sliderNavigation = null 

     //TODO: this should go to slides actions 
     let slider = _.map(slides, function (slide) { 
      let Background = slide.featured_image_url.full; 
      if(slide.status === 'publish') 
       return <div className="slide" id={slide.id} key={slide.id}><div className="Img" style={{ backgroundImage: `url(${Background})` }} data-src={slide.featured_image_url.full}></div></div> 
     }); 

     if(slides.length > 1) { 

      sliderNavigation = <ul className="slider__navigation"> 
       <li data-slide="prev" className="" onClick={this.prev}>previous</li> 
       <li data-slide="next" className="" onClick={this.next}>next</li> 
      </ul> 
     } 

     return <div ref={ 
      (el) => this._slider = el 
     } className="slider-attached" 
        data-navigation="true" 
        data-columns={columns} 
        data-dimensions="auto" 
        data-slides={slides.length}> 
        <div className="slides" style={{ transform: `translate(${currentPosition}%, 0px)`, left : 0 }}> {slider} </div> 

        {sliderNavigation} 
      </div> 
    } 
} 

export default Slider; 

und hier habe ich meine Handlungen für Schieber

import * as types from './actionTypes'; 
import axios from 'axios'; 
import _ from 'underscore'; 


//TODO: this should be accessed from DataService 
if (process.env.NODE_ENV === 'development') { 
    var slidesEndPoint = 'http://dev.server/wp-json/wp/v2/slides'; 
} else { 
    var slidesEndPoint = 'http://prod.server/wp-json/wp/v2/slides'; 
} 

export function getSlides() { 
    return dispatch => { 
     dispatch(setLoadingState()); // Show a loading spinner 

     axios.get(slidesEndPoint) 
      .then(function (response) { 
       dispatch(setSlides(response.data)) 
       dispatch(doneFetchingData(response.data)) 
      }) 
      /*.error((response) => { 
       dispatch(showError(response.data)) 
      })*/ 

    } 
} 


function setSlides(data) { 
    return { 
     type: types.SLIDES_SUCCESS, 
     slides: data 
    } 
} 


function setLoadingState() { 
    return { 
     type: types.SHOW_SPINNER, 
     loaded: false 
    } 
} 

function doneFetchingData(data) { 
    return { 
     type: types.HIDE_SPINNER, 
     loaded: true, 
     slides: data 
    } 
} 

function showError() { 
    return { 
     type: types.SHOW_ERROR, 
     loaded: false, 
     error: 'error' 
    } 
} 

Antwort

1

Grund ist, componentDidMount wird nur einmal aufgerufen, nur nach dem i nitial rendering, da Sie die Daten asynchron holen, also bevor Sie die Daten erhalten, wird die Slider-Komponente gerendert.

So müssen Sie componentwillreceiveprops Lifecycle-Methode verwenden.

componentDidMount:

componentDidMount() wird aufgerufen, unmittelbar nachdem eine Komponente montiert ist. Initialisierung, die DOM-Knoten erfordert, sollte hier gehen. Wenn Sie Daten von einem Remote-Endpunkt laden müssen, ist dies ein guter Ort, um die Netzwerkanforderung instanziieren . Wenn in dieser Methode der Status gesetzt wird, wird ein erneutes Rendering ausgelöst.

componentWillReceiveProps:

componentWillReceiveProps() ist, bevor ein Bauteil montiert aufgerufen neue Stützen aufnimmt. Wenn Sie den Status als Antwort auf Prop-Änderungen aktualisieren müssen (z. B. um ihn zurückzusetzen), können Sie this.props und nextProps vergleichen und Zustandsübergänge unter Verwendung von this.setState() in diese Methode durchführen.

schreibt es so:

componentWillReceiveProps(nextProps){ 
    if(nextProps.slides){ 
     let {slides} = nextProps.props 
     let slidesLength = slides.length;   

     this.hammer = Hammer(this._slider) 
     this.hammer.on('swipeleft', this.next); 
     this.hammer.on('swiperight', this.prev); 
     this.setState({slidesLength}) 
    } 
} 
0

Soweit ich verstehe, Sie sind einen axios Aufruf tun, um die Daten zu holen und setzen sie dann in den Minderer, die Sie später zurückkehren werden. Anfangs sind auch die Daten des Druckminderers leer. Jetzt, da componentDidMount nur einmal aufgerufen wird und anfänglich keine Daten vorhanden waren, werden keine Werte angezeigt. Verwenden Sie eine componentWillReceiveProps Funktion

componentWillReceiveProps(nextProps) { 
     //here I try set a state variable on slides 
     let {slides} = nextProps 
     let slidesLength = slides.length 
     this.setState({slidesLength}) 

     this.hammer = Hammer(this._slider) 
     this.hammer.on('swipeleft', this.next); 
     this.hammer.on('swiperight', this.prev); 
    } 
Verwandte Themen