簡體   English   中英

回調函數,負責更新狀態,作為道具傳遞給子組件,而不觸發狀態更新

[英]Callback function, responsible for updating state, passed as props to child component not triggering a state update

回調函數(位於Images組件中)負責進行狀態更新。 我將該功能作為道具傳遞給Modal組件,並且在其中將其傳遞給ModalPanel組件。

該函數用於將狀態屬性display設置為false,這將關閉模式。 當前,該功能無法正常工作。

圖片組件:

class Images extends Component {
  state = {
    display: false,
    activeIndex: 0
  };

  handleModalDisplay = activeIndex => {
    this.setState(() => {
      return {
        activeIndex,
        display: true
      };
    });
  };

  closeModal = () => {
    this.setState(() => {
      return { display: false };
    });
  }

  render() {
    const { imageData, width } = this.props;
    return (
      <div>
        {imageData.resources.map((image, index) => (
          <a
            key={index}
            onClick={() => this.handleModalDisplay(index)}
          >
            <Modal
              closeModal={this.closeModal}
              display={this.state.display}
              activeIndex={this.state.activeIndex}
              selectedIndex={index}
            >
              <Image
                cloudName={CLOUDINARY.CLOUDNAME}
                publicId={image.public_id}
                width={width}
                crop={CLOUDINARY.CROP_TYPE}
              />
            </Modal>
          </a>
        ))}
      </div>
    );
  }
}

export default Images;

模態分量:

const overlayStyle = {
  position: 'fixed',
  zIndex: '1',
  paddingTop: '100px',
  left: '0',
  top: '0',
  width: '100%',
  height: '100%',
  overflow: 'auto',
  backgroundColor: 'rgba(0,0,0,0.9)'
};

const button = {
  borderRadius: '5px',
  backgroundColor: '#FFF',
  zIndex: '10'
};

class ModalPanel extends Component {
  render() {
    const { display } = this.props;
    console.log(display)
    const overlay = (
      <div style={overlayStyle}>
        <button style={button} onClick={this.props.closeModal}>
          X
        </button>
      </div>
    );
    return <div>{display ? overlay : null}</div>;
  }
}

class Modal extends Component {
  render() {
    const {
      activeIndex,
      children,
      selectedIndex,
      display,
      closeModal
    } = this.props;
    let modalPanel = null;
    if (activeIndex === selectedIndex) {
      modalPanel = (
        <ModalPanel display={this.props.display} closeModal={this.props.closeModal} />
      );
    }

    return (
      <div>
        {modalPanel}
        {children}
      </div>
    );
  }
}

export default Modal;

鏈接到代碼https://github.com/philmein23/chez_portfolio/blob/chez_portfolio/components/Images.js

https://github.com/philmein23/chez_portfolio/blob/chez_portfolio/components/Modal.js

您正在通過一種非反應性和低調的方式來處理這種模式。

本質上,在您的方法中,所有模態始終存在,並且當您單擊圖像時, 所有模態的display狀態變為true,並且您與索引號匹配以決定要顯示的內容。 我懷疑由於Modal或Modal Panel中有多個同一個鍵的子代而無法正常工作。

我強烈建議您放棄當前的方法。 這是我的建議:

  1. Images組件中只有一個<Modal/>
  2. selectedImage狀態添加到您的Images組件。 每次單擊圖像時,都將selectedImage設置為該單擊的圖像對象。
  3. selectedImage向下傳遞給Modal以顯示所需的內容。

這樣,在任何時候都只渲染一個模態。 內容根據您單擊的圖像而動態變化。

這是我從您的倉庫中調整的工作代碼:

(我不確定顯示什么為模態內容,所以我顯示圖像的public_id

圖片組件

class Images extends Component {
  state = {
    display: false,
    selectedImage: null
  };

  handleModalDisplay = selectedImage => {
    this.setState({
      selectedImage,
      display: true
    })
  };

  closeModal = () => {
    //shorter way of writing setState
    this.setState({display: false})
  }

  render() {
    const { imageData, width } = this.props;
    return (
      <div>
        <Modal
          closeModal={this.closeModal}
          display={this.state.display}
          selectedImage={this.state.selectedImage}
        />
        {imageData.resources.map((image, index) => (
          <a
            //Only use index as key as last resort
            key={ image.public_id }
            onClick={() => this.handleModalDisplay(image)}
          >
            <Image
              cloudName={CLOUDINARY.CLOUDNAME}
              publicId={image.public_id}
              width={width}
              crop={CLOUDINARY.CROP_TYPE}
            />
          </a>
        ))}
      </div>
    );
  }
}

模態分量

class Modal extends Component {
  render() {
    const { display, closeModal, selectedImage } = this.props;

    const overlayContent = () => {
      if (!selectedImage) return null; //for when no image is selected
      return (
        //Here you dynamically display the content of modal using selectedImage
        <h1 style={{color: 'white'}}>{selectedImage.public_id}</h1>
      )
    }

    const overlay = (
      <div style={overlayStyle}>
        <button style={button} onClick={this.props.closeModal}>
          X
        </button>
        {
          //Show Modal Content
          overlayContent()
        }
      </div>
    );
    return <div>{display ? overlay : null}</div>;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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