React 子组件在第一次加载时不接收道具
React child component does not receive props on first load
我正在父 'wrapper' 组件中获取数据并将其传递给两个子组件。一个子组件接受得很好,另一个没有。
在容器中:
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')
)
在包装器组件中,我渲染了两个组件,触发数据获取并将道具向下传递给子组件(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>
);
}
}
更新:
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)
为什么不一样,请问如何解决?
谢谢,
罗马
我认为问题可能出在您的 select 上,尤其是这一个,其组成部分被立即执行(没有获取数据值),因此值不会随着记忆而改变。这意味着如果基础数据从获取的数据发生变化,它不会导致组件更新
const mapStateToProps = createStructuredSelector({
visitedCountriesList: getVisitedCountriesList, // should not execute ()
visitedCountriesPolygons: getVisitedCountriesPolygons // should not execute ()
});
通过不立即执行组合的 selector,mapStateToProps 将在每次状态更改时调用它们,它们应该 select 新值并导致您的反应组件自动更新
显然,这是正确的,它只是另一个地方的一个小问题(这里没有粘贴,也没有报告错误)。
经过彻底清理和重构后,它按预期工作。
结论:始终保持代码清洁,使用 linter 并遵循最佳实践:)
我正在父 'wrapper' 组件中获取数据并将其传递给两个子组件。一个子组件接受得很好,另一个没有。
在容器中:
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')
)
在包装器组件中,我渲染了两个组件,触发数据获取并将道具向下传递给子组件(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>
);
}
}
更新: 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)
为什么不一样,请问如何解决?
谢谢, 罗马
我认为问题可能出在您的 select 上,尤其是这一个,其组成部分被立即执行(没有获取数据值),因此值不会随着记忆而改变。这意味着如果基础数据从获取的数据发生变化,它不会导致组件更新
const mapStateToProps = createStructuredSelector({
visitedCountriesList: getVisitedCountriesList, // should not execute ()
visitedCountriesPolygons: getVisitedCountriesPolygons // should not execute ()
});
通过不立即执行组合的 selector,mapStateToProps 将在每次状态更改时调用它们,它们应该 select 新值并导致您的反应组件自动更新
显然,这是正确的,它只是另一个地方的一个小问题(这里没有粘贴,也没有报告错误)。 经过彻底清理和重构后,它按预期工作。
结论:始终保持代码清洁,使用 linter 并遵循最佳实践:)