我正在使用Udemy: The Complete React Native and Redux Course by Stephen Grider学习RN,而我正在使用Firebase创建一个管理应用。
我有来自react-redux
库的连接函数并且有mapStateToProps()
所以每当我的状态发生变化时,我都会在组件中将它们作为道具接收。
我创建了一个从Firebase数据库中获取数据的操作,我将在componentWillMount()
中调用它,但由于获取数据是异步任务,我必须在{{1}中创建我的数据源}。
但是教练说我必须在componentWillReceiveProps()
和createDataSource()
中拨打我的componentWillMount()
我不明白为什么!!如果我在状态中有任何变化(这是我的员工名单),我将收到它们作为道具,所以我认为仅仅在componentWillReceiveProps()
中拨打createDataSource()
就足够了。
有人能为我声明吗?是否有任何我忘记处理的特殊情况?
EmployeeActions.js:
componentWillReceiveProps()
EmployeeList.js:
export const employeesFetch = () => {
const { currentUser } = firebase.auth();
return dispatch => {
firebase
.database()
.ref(`/users/${currentUser.uid}/employees`)
.on("value", snapshot => {
dispatch({ type: EMPLOYEES_FETCH_SUCCESS, payload: snapshot.val() });
});
};
};
所以我正在使用 componentWillMount() {
this.props.employeesFetch();
this.createDataSource(this.props);
}
componentWillReceiveProps(nextProps) {
this.createDataSource(nextProps);
}
createDataSource({ employees }) {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(employees);
}
来展示我从Firebase获取的员工!如果我在ListView
中使用createDataSource()
,我会遇到任何问题吗?
答案 0 :(得分:2)
我还完成了你提到的Udemy课程,首先我要说使用componentWillReceiveProps()和componentWillMount()道具已被弃用,不应再使用了。在新项目中,建议您使用静态getDerivedStateFromProps()和componentDidUpdate()。官方React文档将为您提供有关此主题的其他信息。
但是仅在初始渲染完成后调用componentWillReceiveProps(),因此如果组件在实例化时没有收到道具,则需要在componentWillMount()中进行设置。
修改强> 如果您想坚持新的最佳实践,那么这将是最佳选择:
答案 1 :(得分:1)
我也参加了同样的Udemy课程,并且在我了解到某些React生命周期已被弃用并由其他生命周期替代后,我正在重构代码。
这是我获取和更新的旧逻辑:
state = { dataSource: [] }
componentWillMount() {
const { userCentres } = this.props;
this.props.fetchCentres(userCentres);
this.createDataSource(this.props);
}
componentWillReceiveProps(nextProps) {
this.createDataSource(nextProps);
}
createDataSource({ centresList }) {
this.setState({ dataSource: centresList });
}
我尝试使用static getDerivedStateFromProps
替换当前的逻辑,但由于无法在其作用域内使用关键字this
导致无法使用this.createDataSource(props)
,因此遇到了问题。我还读了“ you probably don't need derived state”,之后决定最好改用getSnapshotBeforeUpdate
和componentDidUpdate
。
getSnapshotBeforeUpdate()在最近渲染的输出提交到例如DOM。它使您的组件可以在DOM可能发生更改之前从DOM捕获一些信息(例如,滚动位置)。 此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
这就是我重构代码的方式:
state = { dataSource: [] }
componentDidMount() {
const { userCentres } = this.props;
this.props.fetchCentres(userCentres);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot) {
this.createDataSource(this.props);
}
}
getSnapshotBeforeUpdate(prevProps) {
if (prevProps.centresList !== this.props.centresList) {
return true;
}
return null;
}
createDataSource({ centresList }) {
this.setState({ dataSource: centresList });
}
尽管我不是100%地确定这是解决问题的最佳方法,但最终还是为我工作。我还应该注意,这是一个PureComponent。