React formik не могу сбросить компонент изображения реакции 17 - PullRequest
0 голосов
/ 24 октября 2019

Я использую formik для форм в новом интерфейсе бэк-офиса, который я строю. Для некоторых форм я сбрасываю некоторые поля после их отправки. все отлично работает с formik ожидать, когда я хочу сбросить поле изображения. Когда форма отправляется, вызывается функция resetForm(), и поля очищаются, за исключением компонента изображения. Я дважды проверяю начальные значения, и значение изображения упирается в его пустое значение. но компонент не обновляется. Я полагаю, что проблема может быть связана с состоянием компонента, или я ошибаюсь?

мой компонент для обработки изображений

   const customStyles = {
  content: {
    top: '80px',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, 0)',
    borderRadius: '6px',
  },
  overlay: {
    backgroundColor: 'rgba(0, 0, 0, .5)',
    zIndex: 2040,
  },
}

interface image {
  alt: string
  created_at: string
  filename: string
  folder: string
  id: number
  updated_at: string
  url: string
}

interface Props {
  [key: string]: any
}

interface State {
  modalOpen: boolean
  [key: string]: any
}

export class ImageInput extends React.PureComponent<Props, State> {
  constructor(props: Props) {
    super(props)

    this.state = {
      image: props.src,
      image_id: props.image ? props.image.id : 0,
      modalOpen: false,
      searchResults: [],
    }
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.image && nextProps.image == null) {
      return { image: 0 }
    } else return null // Triggers no change in the state
  }

  value() {
    return this.state.image_id
  }

  change = (image: image | null) => {
    this.setState(
      {
        image: image,
        image_id: image ? image.id : null,
      },
      () => {
        if (this.props.onChange) {
          // Need to match format of onChange events
          this.props.onChange({
            target: {
              type: 'image-select',
              value: this.value(),
              name: this.props.name,
            },
          })
        }
      }
    )
  }

  search = (e: React.ChangeEvent<HTMLInputElement>): void => {
    const val = e.target.value.toLowerCase()

    delay(async () => {
      try {
        const json = await media.search(val)

        this.setState({ searchResults: json })
      } catch (error) {
        toastr.error('Search failed', error)
      }
    }, 200)
  }

  renderResults = () => {
    const { searchResults } = this.state

    const results = searchResults.map((r: image) => (
      <Col
        sm={2}
        className="search_item"
        key={r.id}
        onClick={() => this.change(r)}
      >
        <div id="image_container">
          <img
            src={staticFileUrl('img', imagePath(r.folder, r.filename, true))}
          />
        </div>
        <span className="filename">{r.filename}</span>
      </Col>
    ))
    return results
  }

  render() {
    console.dir(this.props)
    const { image } = this.state

    // Selected image
    let imageSrc: string | undefined

    if (image && image.url && image.thumbnail) {
      imageSrc = image.url
    }

    if (image && image.folder && image.filename) {
      // Selected image
      imageSrc = staticFileUrl(
        'img',
        imagePath(image.folder, image.filename, false)
      )
    }

    return (
      <Grid style={{ marginBottom: 15 }}>
        <Row center="md">
          <Col md={12}>
            <figure>
              <img
                width={100}
                id={this.props.name}
                src={imageSrc ? imageSrc : ''}
              />
            </figure>
          </Col>
        </Row>
        <Row
          center="md"
          between="md"
          style={{
            maxWidth: 400,
            margin: 'auto',
          }}
        >
          <Col md={12} lg={6}>
            <Button
              type="button"
              onClick={() => this.setState({ modalOpen: true })}
            >
              {`Select ${this.props.display_name}`}
            </Button>
          </Col>
          <Col md={12} lg={6}>
            <Button type="button" onClick={() => this.change(null)}>
              {`Clear ${this.props.display_name}`}
            </Button>
          </Col>
        </Row>
        <Modal
          isOpen={this.state.modalOpen}
          onRequestClose={() => this.setState({ modalOpen: false })}
          style={customStyles}
        >
          <div className="row" id="modal_header">
            <div className="container-fluid">
              <h4>Select image</h4>
            </div>
          </div>
          <Row>
            <Col sm={3}>
              <h4>Search media</h4>
              <input
                type="text"
                className="form-control"
                id="media_search"
                placeholder="Split terms by comma"
                onChange={this.search}
              />
              <h4>Preview:</h4>
              <div id="media_preview">
                <img src={imageSrc} />
              </div>
            </Col>
            <Col sm={9}>
              <h4>Result</h4>
              <Row id="media_results">{this.renderResults()}</Row>
            </Col>
          </Row>
        </Modal>
      </Grid>
    )
  }
}
...