reactjs - 使用 Redux 反应生命周期 (componentDidMount)
问题描述
我对 React Lifecycle 有点困惑,特别是componentDidMount如何与 redux 交互。
这是场景:我有一个连接到 redux 存储的组件,我不知道是否应该在更新 redux 存储并且连接组件中的 props 更改时再次调用 componentDidMount。现在,每次道具更改时都会重新安装一个组件。但是,我有另一个单独的连接组件,当它的道具改变时不会重新安装。所以现在我因为这种不一致的行为而迷路了。
我环顾四周,但有些答案,例如 为什么我重新渲染时没有调用 componentDidMount?多次调用 ComponentDidMount让我感到困惑。
这是一个在 props 更改时没有正确更新的代码示例
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from "redux";
import PropTypes from 'prop-types';
/* material UI */
import Collapse from '@material-ui/core/Collapse';
import Divider from '@material-ui/core/Divider';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Tooltip from '@material-ui/core/Tooltip';
/* Icons */
import {Copy,FolderMinus,FolderPlus} from 'react-feather';
/* Our Components */
import { history } from '../../redux/store/index';
import { getClusters, setCluster, toggleClusters } from '../../redux/actions/ClusterActions';
class SideClustersList extends Component{
constructor(props){
super(props);
}
componentDidMount(){
/* get a list of clusters based on the apiurl */
console.log("props get clusters")
console.log(this.props.base_url)
this.props.getClusters(this.props.base_url);
}
setCurrentCluster(cluster) {
this.props.setCluster(this.props.base_url, cluster)
// Switch tabs to display selected cluster
history.push("/clusters")
}
render(){
const { classes,clusters, open } = this.props;
return (
<React.Fragment>
<ListItem button className={classes.nested} onClick={this.handleClick}>
<Tooltip id="tooltip-bottom" title="Clusters" placement="top">
<ListItemIcon >
{open ? <FolderMinus/>:<FolderPlus/>}
</ListItemIcon>
</Tooltip>
<ListItemText primary="Clusters" /></ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<Divider />
<List component="div" disablePadding>
{clusters ? (
clusters.map(cls =>(
<ListItem button key={cls.clusterName} component='a'
/*href={'/clusters/'+this.props.accounts[0]['account_name']+'/'+cls.clusterName}*/
onClick={() => this.setCurrentCluster(cls.clusterName)}>
<Tooltip id="tooltip-top" title={cls.clusterName} placement="top">
<ListItemIcon>
<Copy />
</ListItemIcon>
</Tooltip>
<ListItemText primary={cls.clusterName} />
</ListItem>
))): null}
</List>
</Collapse>
</React.Fragment>
)
}
handleClick = () => {
this.props.toggleClusters(!this.props.open)
};
}
SideClustersList.propTypes = {
getClusters: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
account_name: state.accounts.item.account_name,
base_url: state.accounts.item.apiurl,
cluster: state.clusters.item,
clusters: state.clusters.items,
open: state.clusters.open,
});
function mapDispatchToProps(dispatch) {
return bindActionCreators({getClusters, setCluster, toggleClusters}, dispatch)
}
export default connect(
mapStateToProps, mapDispatchToProps
)(SideClustersList);
解决方案
当 Redux 获得新数据时,它会通过 connect down 到所有连接的组件来触发 props 更改。根据存储更改,组件的行为方式有一些可能性:
当与 store 的连接不影响组件的父组件时,它将启动常规组件生命周期:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
发生这种情况时,组件将不会调用
componentDidMount
,如您所见。当孩子的父母受到影响时,有可能将该组件从dom中移除并重新进入。什么时候可以?例如,当父组件决定提供的道具是新的并且它应该重新渲染其所有子组件时。发生这种情况时,您输入从 dom 中卸载组件并被
componentWillUnmount()
调用然后使用常规生命周期方法再次安装的路径:constructor()
static getDerivedStateFromProps()
render()
componentDidMount()
您可以在此处阅读有关和解的更多信息:https ://reactjs.org/docs/reconciliation.html
推荐阅读
- cassandra - 如何在 cassandra 中存储用户答案?
- python - 如何选择正确的 python 类
- java - 使用多个字符串分隔符拆分字符串
- php - PHP:将数组分配给变量
- ios - 在 iOS 和 GPU 中使用 .tflite
- opencv - OpenCV中Matx的dot()和ddot()之间的区别
- java - 您如何以编程方式访问已解决的实现依赖项?
- node.js - NodeJS express 上的路由器
- javascript - 即使在启用标头后,PayPal节点sdk也会导致CORs错误“预检请求不允许重定向”
- excel - 多个 IF 的 Excel 函数