如何解决为什么我不能在componentDidMount中收到引用?反应
我正在使用react 16.13.1和react-dom 16.13.1。我使用React.createRef()创建一个引用并附加到我自己定义的组件上,然后我想使用在该组件中定义的方法,但由于.current为空,所以它不起作用,这是我的代码。
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,});
this.picturesRef.current.setFileList(imgs);
}
render() {
const {
categories,isLoading,name,} = this.state;
return (
<Card title={<div>Add Product</div>} loading={isLoading}>
<Form
{...layout}
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
initialValues={{
name,}}
>
<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>
);
}
}
(附言:当我在onFinish()中使用this.picturesRef.current时,它工作正常。)
下面是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;
在componentDidMount的第一行中,我打印出this.picturesRef,然后发生了一些奇怪的事情: 在第一行中,它表明current为null,但是当我打开它时,似乎它具有内容。但是,当我打印.current时,它仍然为null。
解决方法
正如我在OP的问题部分中指出的那样,我注意到Card
组件具有道具loading
<Card title={<div>Add Product</div>} loading={isLoading}>
<Form>
<Item>
<PicturesWall ref={this.picturesRef} />
...
这使我相信Card
组件具有阻止其子对象在完成加载之前进行渲染的条件,例如,它代替了在加载时渲染其子对象,而是呈现“ is-正在加载”类型的组件。
在这种情况下,this.picturesRef.current
将在null
的生命周期中返回componentDidMount
,因为ref
不会引用任何东西,因为它在DOM中还没有那个时候。
我的原始评论:
,此post可能会有所启发。你有道具,例如 卡让我觉得也许您最初是在渲染 DOM上某些“正在加载”类型的组件,而不是 Card的子级,例如PicturesWall组件。这可能就是为什么 在componentDidMount生命周期中无法访问PicturesWall ref
这并不能直接回答您的问题,但是我认为您可能在做出错误反应。
您的componentDidMount
函数似乎基本上只是从props派生状态(然后在后勤组件上调用函数)。您可以在类组件的构造函数中导出状态,例如像
constructor(props) {
const product = props.products.find((item)=>item._id === props.match.params.id);
const {name,price,categoryId,imgs,desc,detail} = product;
this.state = {name,detail};
}
然后,代替使用setFileList
函数,您可以类似地将fileList
向下传递给PictureWall
作为道具,例如
<PicturesWall fileList={this.state.imgs} />
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。