【发布时间】:2020-08-24 05:05:55
【问题描述】:
我正在使用 react 16.13.1 和 react-dom 16.13.1。我使用 React.createRef() 创建了一个 ref 并附加到我自己定义的组件。然后我想使用我在该组件中定义的方法,但它不起作用,因为 .current 为 null。这是我的代码。
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. 当我在 onFinish() 中使用 this.picturesRef.current 时,它工作正常。)
以下是PictureWall中的代码
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;
在 componentDidMount 的第一行,我打印出 this.picturesRef,然后发生了一些奇怪的事情: 在第一行中,它显示 current 为空,但是当我打开它时,它似乎有内容。但是,当我打印 .current 时,它仍然为空。
【问题讨论】:
-
PicturesWall是如何使用 ref 的? -
PictureWall 类中有一个方法,在该方法中我使用给定的参数设置状态。
-
能贴一下PictureWall组件代码
-
这个post 可能会有所启发。您在
Card上有诸如loading之类的道具,这使我认为您最初可能是在DOM 上渲染某些“正在加载”类型的组件,而不是Form的子组件,例如PicturesWall组件。这可能就是为什么在componentDidMount生命周期中无法访问PicturesWallref -
出现“奇怪”是因为 Chrome 检查器打印的是活动对象,而不是快照;当你展开对象来检查它时,
current属性已经设置好了。
标签: javascript reactjs frontend