我是React编码方面的新手,我刚刚加入一个新组织,需要将该代码发送以供审核。该功能正常工作,但在我看来,组件中的代码变得很冗长, Submithandler方法使我多次迭代数组,但我不知道如何进行其他操作。有什么方法可以缩短代码以使其看起来更好并提高性能?目前花了很长时间单击提交后需要显示数据的时间,看起来迭代oof数组需要时间。
此外,如果我在单击“提交”按钮后关闭浏览器,则仍在执行ajax待处理的请求。我要结束请求并在我关闭浏览器或导航到其他页面后停止加载。myRequestor是第三方组织的可用于发送请求的库。请帮助我缩短代码并解决未解决的ajax请求问题。下面是我尝试执行的代码。
const propTypes = {
name: PropTypes.string,
tenant: PropTypes.arrayOf(PropTypes.any),
myRequestor: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};
let myRequestor = null;
const CallerUtil = () => {
myRequestor = React.useContext(MyRequestorContext);
return <ApplicationLoadingOverlay isOpen backgroundStyle="clear" />;
}
class ReadinessComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
body: '',
tenant: null,
error: null,
errorMsg: '',
isOpen: false,
showTable: false,
isInvalid: false,
isLoading: false,
tenantId: '',
items: [],
tenantItems : null
};
this.onChangeTenantDropDown = this.onChangeTenantDropDown.bind(this);
this.onSubmitHandler = this.onSubmitHandler.bind(this);
this.onChangeHandler = this.onChangeHandler.bind(this);
this.tenantIdHandler = this.tenantIdHandler.bind(this);
this.onClose = this.onClose.bind(this);
this.addNewTenant = this.addNewTenant.bind(this);
this.fetchInitial = this.fetchInitial.bind(this);
}
componentDidMount() {
this.mounted = true;
this.setState({ isLoading: true });
this.fetchInitial();
}
componentWillUnmount(){
this.mounted = false;
}
onChangeTenantDropDown(value) {
this.setState({
tenant: value,
});
const info = this.state.tenantItems.find(function (t) { return t.name == value })
this.setState({
tenantId: info.id,
});
}
onSubmitHandler() {
if (this.state.body == '') {
this.setState({ isInvalid: true });
return;
}
this.setState({ isLoading: true });
const params = {
"tenantId": this.state.tenantId,
"tenantShortName": this.state.tenant,
"contactName": this.state.body
}
const { request } = myRequestor.get({
url: '/getReadinessCheck',
params: params,
});
// request.then(async ({ data }) => {
request.then(({ data }) => {
console.log(this.mounted);
if (!this.mounted) {
this.setState({ isLoading: false });
return;
}
console.log(data);
let abc = data.find(vrsn => vrsn.name === 'TENANT_ERROR');
if (abc === undefined) {
this.setState({ error: 'Failure', errorMsg:'Invalid Tenant',isLoading: false, isOpen: true, showTable: false, body: '', tenantId: ''});
return;
}
let readinessResp = data.map(version => (version.latest === true ? { ...version, name: version.name.concat('_LATEST') } : version))
readinessResp.sort(function (a, b) {
var textA = a.name.toUpperCase();
var textB = b.name.toUpperCase();
return textA.localeCompare(textB);
});
this.setState({ items: readinessResp, error: 'Success', showTable: true, isLoading: false });
}).catch(error => {
this.setState({ error: 'Failure', errorMsg:'Failure', isLoading: false, isOpen: true, showTable: false ,body: '', tenantId: '' });
});
}
onChangeHandler(event) {
this.setState({
body: event.target.value,
});
}
tenantIdHandler(event) {
this.setState({
tenantId: event.target.value,
});
}
onClose() {
this.setState(prevState => ({
isOpen: !prevState.isOpen,
}));
}
addNewTenant(shortName,tenantId){
const newTenantShortName = shortName;
const newTenantId = tenantId;
const newTenant = {'name':newTenantShortName, 'id':newTenantId};
this.setState({
tenantItems: [...this.state.tenantItems, newTenant]
});
}
fetchInitial() {
this.setState({ isLoading: true });
const { request } = myRequestor.get({
url: '/tenants'
});
request
.then(({ data }) => {
if(data[0].hasOwnProperty("error")){
this.setState({ error: 'Failure', errorMsg:data[0]['error'], isOpen: true, isLoading:
false,tenantItems: [{'name':'Default', 'id':'Default'}]});
return;
}
let tenantsList = data;
let tenants =[];
tenantsList.map(tenant => ( tenants.push({'name':tenant.shortName, 'id':tenant.key})))
this.setState({
tenantItems: tenants,isLoading: false
});
})
.catch((error) => {
this.setState({ error: 'Failure', isOpen: true, isLoading: false});
});
}
render() {
const {
error, isOpen, body,showTable
} = this.state;
if (this.state.tenantItems === null) {
return <CallerUtil />;
}
if(this.state.isLoading){
return <ApplicationLoadingOverlay isOpen backgroundStyle="clear" />;
}
if (showTable) {
return (<div>
<h1>Readiness Status</h1>
<ReadinessComponentView readinessInfo={this.state.items} /></div>);
}
return (
<div className="ruleSupportEvaluation">
<Grid>
<Grid.Row>
<Grid.Column>
<Heading level={1}>Readiness Check</Heading>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column className="ruleSupportEvaluation" large={3} medium={3}>
<div>
<Heading className="info" level={3}>About</Heading>
<Divider />
<Text className="description" fontSize={18}>
Readiness Check
</Text>
</div>
</Grid.Column>
<Grid.Column className="ruleSupportEvaluation" large={8} medium={8}>
<div>
<div className="readinessComponent">
<Tenant
tenant={this.state.tenantItems}
change={this.onChangeTenantDropDown}
/>
<ModalManagerExample addNewTenant={this.addNewTenant} />
</div>
<InputField type="text" label="Tenant-Id" value={this.state.tenantId} placeholder="Tenant Id" onChange={this.tenantIdHandler}/>
<InputElement isInvalid ={this.state.isInvalid} change={this.onChangeHandler} value={body} />
<Submit click={this.onSubmitHandler} />
{error === 'Failure' &&
(
<Notification
errorMessage={this.state.errorMsg}
close={this.onClose}
isOpen={isOpen}
/>
)
}
</div>
</Grid.Column>
</Grid.Row>
</Grid>
</div>
);
}
}
ReadinessComponent.propTypes = propTypes;
export default ReadinessComponent;
答案 0 :(得分:1)
@charlietfl提到-codereview.stackoverflow.com可能是您最好的选择,
第一个快速获胜的方法是从构造函数中提取所有.bind(this)
的东西,并为这些方法在类中定义它们,如下所示:
之前:
onChangeTenantDropDown(value) {
this.setState({
tenant: value,
});
const info = this.state.tenantItems.find(function (t) { return t.name == value })
this.setState({
tenantId: info.id,
});
}
之后:
onChangeTenantDropDown = (value) => {
this.setState({
tenant: value,
});
const info = this.state.tenantItems.find(function (t) { return t.name == value })
this.setState({
tenantId: info.id,
});
}
请注意箭头功能。
您也可以直接将状态设置为类属性,因此从定义状态的位置删除this.
并将其移至构造函数之外,即:
class ReadinessComponent extends Component {
state = {
body: '',
tenant: null,
error: null,
errorMsg: '',
isOpen: false,
showTable: false,
isInvalid: false,
isLoading: false,
tenantId: '',
items: [],
tenantItems : null
};
...
}
现在您也可以完全删除构造函数了:)
希望这能使您至少部分到达那里
如果您是新手,完全建议学习Hooks,它确实可以帮助清理此类组件-以下是一些链接:
编辑
针对您的评论:
onSubmitHandler = async () => {
const { body, tenantId, tenant: tenantShortName, body: contactName } = this.state;
if (!body) {
this.setState({ isInvalid: true });
return;
}
this.setState({ isLoading: true });
const params = {
tenantId,
tenantShortName,
contactName,
};
try {
const { request } = myRequestor.get({
url: '/getReadinessCheck',
params,
});
const { data } = await request;
if (!this.mounted) {
this.setState({ isLoading: false });
return;
}
let abc = data.find((vrsn) => vrsn.name === 'TENANT_ERROR');
if (abc === undefined) {
this.setState({
error: 'Failure',
errorMsg: 'Invalid Tenant',
isLoading: false,
isOpen: true,
showTable: false,
body: '',
tenantId: '',
});
return;
}
let readinessResp = data.map((version) =>
version.latest === true ? { ...version, name: version.name.concat('_LATEST') } : version,
);
readinessResp.sort(function (a, b) {
var textA = a.name.toUpperCase();
var textB = b.name.toUpperCase();
return textA.localeCompare(textB);
});
this.setState({ items: readinessResp, error: 'Success', showTable: true, isLoading: false });
} catch (err) {
this.setState({
error: 'Failure',
errorMsg: 'Failure',
isLoading: false,
isOpen: true,
showTable: false,
body: '',
tenantId: '',
});
}
};