Javascript 使用回调从this.setState调用迁移到useState和useEffect
我已经使用新的react挂钩将近4个月了,这对于创建react组件来说是一个很大的调整。目前,我正在尝试从类组件迁移到功能组件,但遇到了一些问题。 例如,让我们讨论这个案例,比较函数和类组件,以更好地理解这个问题Javascript 使用回调从this.setState调用迁移到useState和useEffect,javascript,reactjs,ecmascript-6,react-hooks,Javascript,Reactjs,Ecmascript 6,React Hooks,我已经使用新的react挂钩将近4个月了,这对于创建react组件来说是一个很大的调整。目前,我正在尝试从类组件迁移到功能组件,但遇到了一些问题。 例如,让我们讨论这个案例,比较函数和类组件,以更好地理解这个问题 class UserInformation extends React.Component { state = { isBusy: false, }; updateImage = (uploadedImageData: IUploadImage
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;
类用户信息扩展了React.Component{
状态={
isBusy:false,
};
updateImage=(uploadedImageData:IUploadImage):void=>{
常量图像数据={
ImageData:base64ToArrayBuffer(上传的ImageData.ImageData.ImageData),
文件名: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;
返回(
);
}
导出默认用户信息;
这是UserInformation的功能组件版本
const UserInformation=(道具)=>{
const[isBusy,setIsBusy]=useState(false)
const updateImage=(uploadedImageData:IUploadImage):void=>{
常量图像数据={
ImageData:base64ToArrayBuffer(上传的ImageData.ImageData.ImageData),
文件名:uploadedImageData.FileName,
};
setIsBusy(true);
};
constdeleteImage=():void=>setIsBusy(true);
useffect(()=>{
如果(忙){
updateSettingsUserImage(props.selectedUser,imageData)
。然后(()=>setIsBusy(false));
}
},[isBusy]);
useffect(()=>{
如果(忙){
删除设置使用图像(props.selectedUser)
。然后(()=>setIsBusy(false));
}
},[isBusy]);
const{selectedUser}=this.props;
返回(
);
}
导出默认用户信息;
我们可以看到,在一个功能组件中,无论是否触发了updateImage或deleteImage,在这两种情况下都会运行2个useEffects并进行API调用。但在类组件中,API调用将在setState回调中处理,并且只请求一个API调用。
一个选项是为imageData添加另一个状态,并在其useEffect依赖项列表中使用它。但是如果我们没有图像数据,一切都依赖于isBusy怎么办。处理这种情况的最佳方法是什么?为什么您甚至需要在该组件中设置状态?还要注意的是,不仅仅是将类组件转换为功能组件,因为它的新颖性,基于类的组件仍然占有一席之地。但你的例子实际上是一个很好的候选人
constuserinformation=({props})=>{
const[isBusy,setBusy]=useState(false)
const updateImage=async(uploadedImageData:IUploadImage):void=>{
setBusy(真);
常量图像数据={
ImageData:base64ToArrayBuffer(上传的ImageData.ImageData.ImageData),
文件名:uploadedImageData.FileName,
};
等待更新设置使用图像(props.selectedUser,imageData)
挫折(假);
};
const deleteImage=async():void=>{
setBusy(真);
等待删除设置使用图像(道具选择用户);
挫折(假);
}
const{selectedUser}=props;
返回(
);
}
导出默认用户信息;
那么如何使用isBusy?我需要它在抓取时处理动画。好的,如果你需要它,请检查更新的答案
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;