簡體   English   中英

使用 state 的道具替代組件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM