我正在尝试创建一个自定义的提交按钮组件,该组件将自行处理按钮的禁用启用功能。到目前为止,我知道了:
按钮组件:
import * as React from 'react';
import Promise = require('promise');
let isDisabled = false;
const buttonClickHandler = onClick => {
return new Promise((resolve, reject) => {
console.log('inside promise');
isDisabled = true;
onClick();
return resolve(true);
});
};
export const SubmitButton = ({
type,
className,
onClick,
buttonStyle = {},
children
}) => {
return (
<button
type={type || 'submit'}
className={className}
onClick={() =>
buttonClickHandler(onClick).then(() => {
console.log('after promise');
isDisabled = false;
})
}
style={buttonStyle}
disabled={isDisabled}
>
{children}
</button>
);
};
export default SubmitButton;
我这样称呼它:
<SubmitButton type="button" className="btn btn-primary" onClick={this.submitForm}>
Submit
</SubmitButton>
表单提交功能是:
public submitForm = () => {
setTimeout(() => {
console.log('waiting done');
}, 5000);
};
所以预期的输出是
inside promise
----等待5000毫秒----waiting done
after promise
但是我看到了inside promise
after promise
----等待5000毫秒----waiting done
所以我做错了什么?而且该按钮也没有被禁用。
向按钮添加状态,以及用于管理状态的内部onClick处理程序
const SubmitButton = ({
type,
className,
onClick,
buttonStyle = {},
children
}) => {
const [isDisabled, setIsDisabled] = useState();
const clickHandler = async () => {
setIsDisabled(true);
await dbCall();
console.log("after promise");
setIsDisabled(false);
onClick();
}
return (
<button
type={type || "submit"}
className={className}
onClick={clickHandler}
style={buttonStyle}
disabled={isDisabled}
>
{children}
</button>
);
};
演示
NOTE:现在的缺点是异步DB调用与按钮的onClick and内部状态紧密相关。这就是为什么通常应将按钮用作不受控制的“输入”,这意味着它们不应具有自己的内部状态,而应将有状态逻辑放到父组件中,并将disabled
属性作为道具传递。使该按钮可用于任何父组件。