Я использую 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>
)
}
}