当前位置: 首页 > 知识库问答 >
问题:

使用回调从this.setState调用迁移到useState和useEffect

笪成周
2023-03-14

我已经使用新的react挂钩将近4个月了,这对于创建react组件来说是一个很大的调整。目前,我正在尝试从类组件迁移到功能组件,但遇到了一些问题。例如,让我们讨论这个案例,比较函数和类组件,以更好地理解这个问题。

class UserInformation extends React.Component {
    state = {
        isBusy: false,
    };

    updateImage = (uploadedImageData: IUploadImage): void => {
        const imageData = {
            ImageData: base64ToArrayBuffer(uploadedImageData.ImageData.ImageData),
            FileName: uploadedImageData.FileName,
        };

        this.setState({ isBusy: true }, () => {
            this.props.updateSettingsUserImage(this.props.selectedUser, imageData)
                .then(() => this.setState({ isBusy: false }));
        });
    };

    deleteImage = (): void => {
        this.setState({ isBusy: true }, () => {
            this.props.deleteSettingsUserImage(this.props.selectedUser)
                .then(() => this.setState({ isBusy: false }));
        });
    };

    const { selectedUser } = this.props;

    return (
        <BaseInfoCardHeader
           withUploadableAvatar
           style={{ margin: '0 -12px' }}
           name={selectedUser.FullName}
           deleteImage={this.deleteImage}
           updateImage={this.updateImage}
           photopath={selectedUser.Photopath}                        
        />
    );
}

export default UserInformation;

这是UserInformation的功能组件版本

const UserInformation=(道具)=

    const updateImage = (uploadedImageData: IUploadImage): void => {
        const imageData = {
            ImageData: base64ToArrayBuffer(uploadedImageData.ImageData.ImageData),
            FileName: uploadedImageData.FileName,
        };
        setIsBusy(true);
    };

    const deleteImage = (): void => setIsBusy(true);

    useEffect(() => {
       if (isBusy) {
          updateSettingsUserImage(props.selectedUser, imageData)
             .then(() => setIsBusy(false));
       }
    }, [isBusy]);

   useEffect(() => {
       if (isBusy) {
          deleteSettingsUserImage(props.selectedUser)
             .then(() => setIsBusy(false));
       }
    }, [isBusy]);

    const { selectedUser } = this.props;

    return (
        <BaseInfoCardHeader
           withUploadableAvatar
           style={{ margin: '0 -12px' }}
           name={selectedUser.FullName}
           deleteImage={this.deleteImage}
           updateImage={this.updateImage}
           photopath={selectedUser.Photopath}                        
        />
    );
}

export default UserInformation;

我们可以看到,在一个功能组件中,无论是触发updateImage还是deleteImage,在这两种情况下都会运行useEffects并进行API调用。但在类组件中,API调用将在setState回调中处理,并且只请求一个API调用。一个选项是为imageData添加另一个状态,并在其useEffect依赖项列表中使用它。但是如果我们没有图像数据,一切都取决于它是否繁忙呢。处理这种情况的最佳方法是什么?

共有1个答案

秦宁
2023-03-14

为什么您甚至需要在这个组件中设置状态?还要注意的是,不仅仅是将类组件转换为功能组件,因为它的新颖性,基于类的组件仍然占有一席之地。但你的例子实际上是一个很好的候选人。

    const UserInformation = ({props}) => {
        const [isBusy, setBusy] = useState(false)
        const updateImage = async (uploadedImageData: IUploadImage): void => {
            setBusy(true);
            const imageData = {
                ImageData: base64ToArrayBuffer(uploadedImageData.ImageData.ImageData),
                FileName: uploadedImageData.FileName,
            };
            await updateSettingsUserImage(props.selectedUser, imageData)
            setBusy(false);
        };

        const deleteImage = async (): void => {
          setBusy(true);
          await deleteSettingsUserImage(props.selectedUser);
          setBusy(false);
        }

        const { selectedUser } = props;

        return (
            <BaseInfoCardHeader
               withUploadableAvatar
               style={{ margin: '0 -12px' }}
               name={selectedUser.FullName}
               deleteImage={this.deleteImage}
               updateImage={this.updateImage}
               photopath={selectedUser.Photopath}                        
            />
        );
    }

    export default UserInformation;
 类似资料:
  • 我有一个flyway项目,在对数据库运行迁移之前,我想运行一个java回调来更改某些sql文件的名称。不幸的是,迁移首先针对数据库运行,然后调用回调来更改文件名。 这是我的回调类: 但是在< code>schema_version表中,我看到以下条目: 它应该说 如何让flyway在运行迁移之前更改文件名? 编辑1:所以看起来flyway正在运行迁移,然后执行回调以更改文件名,然后再次运行迁移,因

  • 我有一个数据库,其中包含经常需要修改的视图和存储过程。我希望能够将这些视图存储在另一个目录中,并在我编写迁移时包含sql代码。基本上,dir结构是 V1__add_view.sql类似于 这目前在psql中有效,但在飞行方式迁移中不起作用。这样做的好处是,当我们想要进行更改时,我们可以就地修改视图,并将其包含在下一次迁移中。它还将消除视图迁移中的大量复制粘贴。 是否有任何方法可以在快速迁移中包含外

  • 嗨,这是我的场景, 我正在尝试将一个应用程序从JBoss5迁移到JBoss7。 我使用的是jboss-as-7.1.1。最终。 我遇到的错误是: 我看了几个带有相同错误消息的讨论,但我就是不知道我做错了什么。 在部署目录中,我只有一个myapp.war.我没有部署。我有一个依赖项(myapp-ejb.jar)部署为一个模块。 我已经按照https://docs.jboss.org/author/d

  • 问题内容: 我正在从表单组件获取数据,并尝试使用此数据设置应用程序组件的状态。 但是,state.data是一个空对象,不会更新数据。在设置模型数据是否存在之前,我会控制台记录模型数据。他们是模型中的数据。 问题答案: 是React中的异步调用。因此,您不太可能在下一行获得更新的状态值。要在状态更新成功后检查更新后的值,可以签入回调处理程序。 改变这个 至

  • 我刚刚从eclipse转移到IntelliJ。我有一个Spring启动项目,在eclipse中运行完美。但是当我试图在IntelliJ上运行它时,我得到了“进程完成并退出代码1”,我已经尝试了所有接下来的解决方案: https://stackoverflow.com/search?q=eclipseintellijSpring靴 但什么都不管用。有什么建议吗?Spring启动配置

  • 在过去的两个星期里,我一直在努力用Apache Ivy来管理依赖关系,但是每个人在网上谈论的明显的易用性(一旦maven/gradle/apache-ivy用于DM)已经避开了我。有人能帮忙看看我做错了什么吗?我真的很感激。 我正在尝试将现有的Spring/JPA Hibernate应用程序迁移到最新的Spring和Hibernate发行版: 我的环境: ivy.xml: ivysettings.