[英]Alternative to component using props for state
我有一个底层组件,用于在我的应用程序中显示成功/错误消息。 目前它正在为它的 state 使用道具,直到这一点。 我面临的问题是,当在某个组件中返回时,state 在组件渲染一次后不会改变。 IE 消息将正确显示一次,然后不再显示,因为 state 保持设置为 false。
这是渲染组件的 function。 这个 function 位于父组件中。
renderSnackBar(type, message) {
console.log('snackbar function invoked');
return <Snackbar open={true} type={type} message={message} />
}
这是子组件
class MySnackbar extends React.Component {
constructor(props) {
super(props);
this.state = {
open: this.props.open,
};
}
handleClose = (event, reason) => {
if (reason === 'clickaway') {
return;
}
this.setState({ open: false });
};
render() {
const { type, message } = this.props
let icon = <SuccessIcon color={colors.lightBlue} />
let color = colors.lightBlue
console.log('state', this.state, 'props', this.props);
switch (type) {
case 'Error':
icon = <ErrorIcon color={colors.red} />
color = colors.red
break;
case 'Success':
icon = <SuccessIcon color={colors.lightBlue} />
color = colors.lightBlue
break;
case 'Warning':
icon = <WarningIcon color={colors.orange} />
color = colors.orange
break;
case 'Info':
icon = <InfoIcon color={colors.lightBlue} />
color = colors.lightBlue
break;
default:
icon = <SuccessIcon color={colors.lightBlue} />
color = colors.lightBlue
break;
}
return (
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={this.state.open}
autoHideDuration={6000}
onClose={this.handleClose}
message={
<div style={{ padding: '12px 24px', borderLeft: '5px solid '+color, borderRadius: '4px'}}>
{icon}
<div style={{ display: 'inline-block', verticalAlign: 'middle', maxWidth: '400px' }}>
<Typography variant='body1' style={{ fontFamily: 'Montserrat-SemiBold', fontSize: '12px' }}>{type}</Typography>
<Typography variant='body1' style={{ fontFamily: 'Montserrat-Medium', fontSize: '10px', color: colors.darkGray }} noWrap>{message}</Typography>
</div>
</div>
}
action={[
<IconButton
key="close"
aria-label="Close"
color={colors.darkGray}
onClick={this.handleClose}
>
<CloseIcon />
</IconButton>,
]}
/>
);
}
}
export default MySnackbar;
从我收集到的使用道具初始化 state 是一种反模式。 如何在不使用 state 的道具的情况下使用此组件?
基本上,您现在遇到的问题是由于您有 2 个事实来源(1 个来自道具,1 个来自状态)来确定您的 SnackBar 是否应该open
。
所以,我们要做的是让你的组件只有一个事实来源。 通常,我们希望将props
作为事实来源,而不是state
。
我们可以做的是给你的 SnackBar 添加一个名为onClose
的道具,并让 SnackBar 在handleClose
中调用 function 。 onClose
应该更改父组件的open
值,因此传递给 SnackBar 的值会相应更新。 现在,SnackBar 不再需要拥有自己的 state,它可以只依赖传递给它的道具。 这是代码沙箱的示例实现。
每当您收到与 state 不同的开放道具时,您都可以使用 getDerivedStateFromProps 更改state
static getDerivedStateFromProps({open}, state) {
if (open !==state.open) {
//use open from props
return {
...state,
open
};
}
// Return null to indicate no change to state.
return null;
}
您现在可能有一个不再关闭的组件,具体取决于您如何调用 renderSnackbar,如果是这种情况,那么我需要了解更多关于如何调用 renderSnackbar function 的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.