2017-11-24 1 views
0

Ich hole Daten in der übergeordneten Wrapper-Komponente und übergebe sie an zwei untergeordnete Komponenten. Eine Kindkomponente erhält sie gut, eine andere nicht.Reagieren untergeordnete Komponente erhält keine Requisiten beim ersten Laden

In Container:

const mapStateToProps = createStructuredSelector({ 
    visitedCountriesList: getVisitedCountriesList(), 
    visitedCountriesPolygons: getVisitedCountriesPolygons() 
}); 

export function mapDispatchToProps(dispatch) { 
    return { 
    loadVisitedCountries:() => { 
     dispatch(loadVisitedCountriesRequest()) 
    }, 
    }; 
} 

in redux Sage I Daten von API holen und speichern sie:

function mapPageReducer(state = initialState, action) { 
    switch (action.type) { 
    case FETCH_VISITED_COUNTRIES_SUCCESS: 
     return state 
     .setIn(['visitedCountriesPolygons', 'features'], action.polygons) 
} 

Selektoren:

const getVisitedCountriesList =() => createSelector(
    getMapPage, 
    (mapState) => { 
    let countriesList = mapState.getIn(['visitedCountriesPolygons', 'features']).map(c => { 
     return { 
     alpha3: c.id, 
     name: c.properties.name 
     } 
    }); 
    return countriesList; 
    } 
) 

const getVisitedCountriesPolygons =() => createSelector(
    getMapPage, 
    (mapState) => mapState.get('visitedCountriesPolygons') 
) 

in einer Wrapper-Komponente machen I zwei Komponenten, die Daten auslösen und Requisiten an untergeordnete Komponenten übergeben (visitedCountriesPolygons und visitedCountrie sList):

class MapView extends React.Component { 
    constructor(props) { 
    super(props) 
    this.props.loadVisitedCountries(); 
    } 

    render() { 
    return (
     <div> 
     <Map visitedCountriesPolygons={this.props.visitedCountriesPolygons} /> 
     <MapActionsTab visitedCountriesList={this.props.visitedCountriesList} /> 
     </div> 
    ); 
    } 
} 

Dann in der ersten Komponente Map Kind erhalte ich auch Requisiten und eine Karte erstellen können:

componentDidMount() { 
    this.map.on('load',() => { 
     this.drawVisitedPolygons(this.props.visitedCountriesPolygons); 
    }); 
}; 

Aber in der zweiten Komponente MapActionsTab Requisiten sind nicht bei Anfangs empfangen machen, aber nur nach jeder Aktualisierung:

class MapActionsTab extends React.Component { 
    constructor(props) { 
    super(props); 
    } 
    render() { 
    let countriesList = this.props.visitedCountriesList.map(country => { 
     return <li key={country.alpha3}>{country.name}</li>; 
    }) || ''; 

    return (
     <Wrapper> 
      <div>{countriesList}</div> 
     </Wrapper> 
    ); 
    } 
} 

UPD: Saga Datenform API fetch:

export function* fetchVisitedCountries() { 
    const countries = yield request 
    .get('http://...') 
    .query() 
    .then((res, err) => { 
     return res.body; 
    }); 
    let polygons = []; 
    yield countries.map(c => { 
    request 
     .get(`https://.../${c.toUpperCase()}.geo.json`) 
     .then((res, err) => { 
     polygons.push(res.body.features[0]); 
     }) 
    }); 
    yield put(fetchVisitedCountriesSuccess(polygons)); 
} 

und ein einfaches Stück Minderer zum Speichern von Daten:

case FETCH_VISITED_COUNTRIES_SUCCESS: 
     return state 
     .setIn(['visitedCountriesPolygons', 'features'], action.polygons) 

Warum ist es anders und wie es zu lösen, bitte?

Dank, Roman

+0

Wohin machen Sie den API-Aufruf? Befindet es sich in 'loadVisitedCountriesRequest'? Kannst du auch dazu Code hinzufügen ... Ich denke, es ist vielleicht ein Problem, wie du mit asynchronen Fluss umgehen kannst. – Dane

+0

hinzugefügt. Ich dachte das gleiche und spielte viel mit dem Versuch, Daten in Saga oder Reducer zu transformieren, um es normalisiert zu speichern, aber es scheiterte aufgrund asynchroner Aktionen. Schluss damit, es im Selektor roh und normalisiert zu speichern. Das ist eine andere Geschichte :) Lange Rede kurzer Sinn, ich wähle Daten aus dem Laden und in einem Fall (Polygone für Map-Komponente) funktioniert es gut, in der zweiten - es ist spät. –

Antwort

0

Anscheinend funktioniert das korrekt und es war nur ein kleines Problem an einem anderen Ort (hier nicht eingefügt und keine Fehler gemeldet). Nach gründlicher Reinigung und Refactoring funktionierte es wie erwartet.

Fazit: Halten Sie Ihren Code immer sauber, verwenden Sie linter und folgen Sie den Best Practices :)

0

Ich denke, das Problem in Ihren Wählern sein kann, insbesondere diese, deren Bestandteile sofort ausgeführt wird (ohne abgerufenen Datenwerte) und damit Werte werden nicht, wie es ändern ist protokolliert. Das bedeutet, dass es nicht eine Aktualisierung der Komponente verursachen sollte die der zugrunde liegenden Datenänderung aus den abgerufenen Daten

const mapStateToProps = createStructuredSelector({ 
    visitedCountriesList: getVisitedCountriesList, // should not execute() 
    visitedCountriesPolygons: getVisitedCountriesPolygons // should not execute() 
}); 

Durch die nicht die komponierten Selektoren sofort ausgeführt wird, mapStateToProps wird sie jedesmal, wenn die Statusänderungen rufen, und sie sollten wählen die neuen Werte und verursachen eine automatische Aktualisierung Ihrer Reaktionskomponente

+0

Ich werde versuchen, damit zu spielen, wahrscheinlich, indem Sie es von meiner Komponente anfordern, aber immer noch ist es nicht konsistent: getVisitedCountriesPolygons führt aus, übergibt Requisiten an die Komponente und rendert erneut; getVisitedCountriesList wird ausgeführt, übergibt jedoch keine Requisiten und rendert sie nicht erneut (oder rendert sie, aber ohne Daten) –

Verwandte Themen