回调函数,负责更新状态,作为道具传递给子组件而不触发状态更新

时间:2017-09-25 03:29:16

标签: reactjs

回调函数(位于Images组件中)负责进行状态更新。我将该函数作为道具传递给Modal组件,并在其中传递给ModalPanel组件。

该函数用于将state属性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

1 个答案:

答案 0 :(得分:0)

你正在通过一种非反应和 hacky 的方式处理这种模式。

基本上,在你的方法中,所有的模态都总是,当你点击图像时,所有模态display状态变为真,你匹配索引号以决定要显示的内容。 由于模态或模态面板中有多个相同键的子项,我怀疑它不起作用。

我强烈建议你放弃当前的做法。这是我的建议:

  1. <Modal/>组件中只有一个Images
  2. selectedImage状态添加到您的Images组件。每次单击图像时,都会将selectedImage设置为该单击的图像对象。
  3. selectedImage传递给Modal以显示您想要的内容。
  4. 这样,始终只渲染 ONE 模式。内容会根据您点击的图片动态变化。

    这是我从您的回购中调整的工作代码:

    (我不确定将什么显示为模态内容,因此我显示图像的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>;
      }
    }