Non*_*Non 3 javascript ecmascript-6 reactjs
我正在尝试从 API 调用中获取一些数据。我正在使用getDerivedStateFromProps,componentDidMount,shouldComponentUpdate andcomponentDidUpdate`。
我这样做是因为我需要userToken在userToken: store.signinScreen.userToken调用GetPassengersData需要userToken从 API 获取数据的函数之前使用它。
这是整个组件:
// imports
class HomeScreen extends Component {
static navigationOptions = {
header: null,
};
state = {
error: false,
};
static getDerivedStateFromProps(props, state) {
if (props.userToken !== state.userToken) {
return { userToken: props.userToken };
}
return null;
}
componentDidMount() {
this.GetPassengersData();
}
shouldComponentUpdate(prevProps, state) {
return this.props !== prevProps;
}
componentDidUpdate(prevProps, prevState) {
const { error } = this.state;
if (!error) {
this.GetPassengersData();
}
}
GetPassengersData = async () => {
const { passengersDataActionHandler, userToken } = this.props;
if (userToken && userToken !== null) {
try {
const response = await fetch(
'http://myAPI/public/api/getPassengers',
{
method: 'POST',
headers: {
Authorization: `Bearer ${userToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
);
const responseJson = await response.json();
if (has(responseJson, 'error')) {
this.setState({ error: true });
Alert.alert('Error', 'Please check your credentials.');
} else {
passengersDataActionHandler(responseJson.success.data);
}
} catch (error) {
this.setState({ error: true });
Alert.alert(
'Error',
'There was an error with your request, please try again later.',
);
}
}
};
render() {
return <TabView style={styles.container} />;
}
}
HomeScreen.defaultProps = {
userToken: null,
};
HomeScreen.propTypes = {
navigation: PropTypes.shape({}).isRequired,
passengersDataActionHandler: PropTypes.func.isRequired,
userToken: PropTypes.oneOfType([PropTypes.string]),
};
export default compose(
connect(
store => ({
userToken: store.signinScreen.userToken,
passengersData: store.homeScreen.passengersData,
}),
dispatch => ({
passengersDataActionHandler: token => {
dispatch(passengersDataAction(token));
},
}),
),
)(HomeScreen);
Run Code Online (Sandbox Code Playgroud)
通过此实现,组件会渲染多次,因此会破坏应用程序。
我可能做错了什么?
首先,您不需要存储userToken在状态中,因为您没有在本地修改它,因此您不需要getDerivedStateFromProps
其次,您需要仅在 prop 更改时触发 componentDidUpdate 中的 API 调用,而不是在没有检查的情况下直接触发,否则 API 中的 setState 成功或错误将导致组件再次重新渲染调用componentDidUpdate,从而再次调用 API 导致无限循环
第三,shouldComponentUpdate 内部比较 props 的检查并不完全正确,因为nestedObjects props 会给出假阴性结果,而且如果您为 props 编写深度相等性检查,则如果状态发生变化,组件将不会重新渲染。
// imports
class HomeScreen extends Component {
static navigationOptions = {
header: null,
};
state = {
error: false,
};
componentDidMount() {
this.GetPassengersData();
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.userToken !== this.props.userToken) {
this.GetPassengersData();
}
}
GetPassengersData = async () => {
const { passengersDataActionHandler, userToken } = this.props;
if (userToken && userToken !== null) {
try {
const response = await fetch(
'http://myAPI/public/api/getPassengers',
{
method: 'POST',
headers: {
Authorization: `Bearer ${userToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
},
);
const responseJson = await response.json();
if (has(responseJson, 'error')) {
this.setState({ error: true });
Alert.alert('Error', 'Please check your credentials.');
} else {
passengersDataActionHandler(responseJson.success.data);
}
} catch (error) {
this.setState({ error: true });
Alert.alert(
'Error',
'There was an error with your request, please try again later.',
);
}
}
};
render() {
return <TabView style={styles.container} />;
}
}
HomeScreen.defaultProps = {
userToken: null,
};
HomeScreen.propTypes = {
navigation: PropTypes.shape({}).isRequired,
passengersDataActionHandler: PropTypes.func.isRequired,
userToken: PropTypes.oneOfType([PropTypes.string]),
};
export default compose(
connect(
store => ({
userToken: store.signinScreen.userToken,
passengersData: store.homeScreen.passengersData,
}),
dispatch => ({
passengersDataActionHandler: token => {
dispatch(passengersDataAction(token));
},
}),
),
)(HomeScreen);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2171 次 |
| 最近记录: |