I'm using react 16.13.1 and react-dom 16.13.1. I create a ref using React.createRef() and attach to a component I defined by myself.And then I want to use a method that I defined in that component, but it does not work because .current is null.Here's my code.
class SomeComponent {
//ref
picturesRef = React.createRef();
richTextRef = React.createRef();
componentDidMount() {
console.log("this.picturesRef", this.picturesRef);
this.setState({ operation: "update" });
const product = this.props.products.find(
(item) => item._id === this.props.match.params.id,
);
const {
name,
price,
categoryId,
imgs,
desc,
detail,
} = product;
this.setState({
name,
price,
categoryId,
imgs,
desc,
detail,
});
this.picturesRef.current.setFileList(imgs);
}
render() {
const {
categories,
isLoading,
name,
price,
categoryId,
desc,
detail,
} = this.state;
return (
<Card title={<div>Add Product</div>} loading={isLoading}>
<Form
{...layout}
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
initialValues={{
name,
price,
categoryId,
desc,
detail,
}}
>
<Item label="Product Pictures" name="imgs">
{/**Here I attach picturesRef to this component */}
<PicturesWall ref={this.picturesRef} />
</Item>
<Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Item>
</Form>
</Card>
);
}
}
(P.S. When I use this.picturesRef.current in onFinish(), it works fine.)
Below is the code in PicturesWall
import React, { Component } from "react";
import { Upload, Modal, message } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { BASE_URL } from "../../config";
import { reqPictureDelete } from "../../api";
function getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
class PicturesWall extends Component {
state = {
previewVisible: false,
previewImage: "",
previewTitle: "",
fileList: [],
};
handleCancel = () => this.setState({ previewVisible: false });
handlePreview = async (file) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj);
}
this.setState({
previewImage: file.url || file.preview,
previewVisible: true,
previewTitle:
file.name ||
file.url.substring(file.url.lastIndexOf("/") + 1),
});
};
handleChange = ({ file, fileList }) => {
console.log("file=", file);
const { response, status } = file;
if (status === "done") {
if (response.status === 0) {
fileList[fileList.length - 1].url = response.data.url;
fileList[fileList.length - 1].name = response.data.name;
} else {
message.error(response.msg, 1);
}
}
if (status === "removed") {
this.deleteImg(file.name);
}
this.setState({ fileList });
};
deleteImg = async (name) => {
const response = await reqPictureDelete(name);
if (response.status === 0) {
message.success("Successfully Delete", 1);
} else {
message.error("Failed", 1);
}
};
getImgNames() {
let imgs = [];
this.state.fileList.forEach((item) => {
imgs.push(item.name);
});
return imgs;
}
setFileList = (imgNames) => {
let fileList = [];
imgNames.forEach((item, index) => {
fileList.push({
uid: index,
name: item,
url: `${BASE_URL}/upload/${item}`,
});
});
this.setState(fileList);
};
render() {
const {
previewVisible,
previewImage,
fileList,
previewTitle,
} = this.state;
const uploadButton = (
<div>
<PlusOutlined />
<div className="ant-upload-text">Upload</div>
</div>
);
return (
<div className="clearfix">
<Upload
action={`${BASE_URL}/manage/img/upload`}
method="post"
listType="picture-card"
fileList={fileList}
onPreview={this.handlePreview}
onChange={this.handleChange}
name="image"
>
{fileList.length >= 4 ? null : uploadButton}
</Upload>
<Modal
visible={previewVisible}
title={previewTitle}
footer={null}
onCancel={this.handleCancel}
>
<img
alt="example"
style={{ width: "100%" }}
src={previewImage}
/>
</Modal>
</div>
);
}
}
export default PicturesWall;
In the first line of componentDidMount, I print out this.picturesRef, and something weird happens:
in the first line, it shows that current is null, but when I open it, it seems that it has content. However, when I print .current, it is still null.