我在父“包装器”组件中获取数据并将其传递给两个子组件。一个子组件很好地接收它,另一个子组件没有。
在容器中:
const mapStateToProps = createStructuredSelector({
visitedCountriesList: getVisitedCountriesList(),
visitedCountriesPolygons: getVisitedCountriesPolygons()
});
export function mapDispatchToProps(dispatch) {
return {
loadVisitedCountries: () => {
dispatch(loadVisitedCountriesRequest())
},
};
}
在redux-saga中的我从API获取数据并存储它们:
function mapPageReducer(state = initialState, action) {
switch (action.type) {
case FETCH_VISITED_COUNTRIES_SUCCESS:
return state
.setIn(['visitedCountriesPolygons', 'features'], action.polygons)
}
选择器:
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')
)
在包装器组件中,我呈现两个组件,触发数据获取并将props传递给子组件(visitedCountriesPolygons和visitedCountriesList):
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>
);
}
}
然后,在第一个子组件Map中,我很好地接收了道具并且可以构建地图:
componentDidMount() {
this.map.on('load', () => {
this.drawVisitedPolygons(this.props.visitedCountriesPolygons);
});
};
但是在第二个组件中,MapActionsTab道具不是在初始渲染时收到的,而是仅在任何更新之后:
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从API获取数据:
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));
}
和一个简单的reducer来存储数据:
case FETCH_VISITED_COUNTRIES_SUCCESS:
return state
.setIn(['visitedCountriesPolygons', 'features'], action.polygons)
为什么它与众不同以及如何解决呢?
感谢, 罗马
答案 0 :(得分:1)
显然,这是正确的,这只是另一个地方的一个小问题(这里没有粘贴,也没有报告错误)。 彻底清理和重构后,它按预期工作。
结论:始终保持代码清洁,使用linter并遵循最佳实践:)
答案 1 :(得分:0)
我认为问题可能在你的选择器中,特别是这个问题,它的组成部分是立即执行的(没有提取的数据值),因此值不会随着它的记忆而改变。这意味着如果基础数据从获取的数据发生更改,它将不会导致组件更新
const mapStateToProps = createStructuredSelector({
visitedCountriesList: getVisitedCountriesList, // should not execute ()
visitedCountriesPolygons: getVisitedCountriesPolygons // should not execute ()
});
通过不立即执行组合选择器,mapStateToProps将在每次状态更改时调用它们,并且它们应该选择新值并导致反应组件的自动更新