gpt4 book ai didi

reactjs - 响应输入 onChange 延迟

转载 作者:行者123 更新时间:2023-12-03 13:07:20 25 4
gpt4 key购买 nike

我有一个带有 onChange 事件处理程序的简单受控输入。

一切都按预期进行,handleChange每次击键都会触发,问题是它非常慢

使用输入时存在非常明显的延迟。我是否需要一些额外的代码才能使其像正常输入一样工作?

我必须去抖动输入吗?

据我所知,文档中没有提到这个问题,我不知道是否需要做一些额外的事情,或者我是否正在使用 onChange 回调错误。

handleChange = (event) => {
this.setState({ itemNumber: event.target.value })
}


<TextField
id="Part #"
label="Part #"
value={this.state.itemNumber}
onChange={this.handleChange}
margin="normal"
/>

组件:

export class Dashboard extends Component {
state = {
report: '',
selectedDate: new Date(),
itemNumber: '',
}

static propTypes = {
classes: object,
headerTitle: string,
userInfo: object,
}

static defaultProps = {
classes: {},
headerTitle: undefined,
userInfo: {},
}

reportSelected = (event) => {
this.setState(() => {
return {
report: event.target.value,
}
})
}

handleDateChange = (date) => {
this.setState({ selectedDate: new Date(date) })
}

handleChange = (event) => {
this.setState({ itemNumber: event.target.value })
}

render () {
const { classes, headerTitle, userInfo } = this.props
return (
<div className={classes.dashboard}>
<HeaderTitle title="Dashboard" />
<Helmet>
<title>{headerTitle}</title>
</Helmet>

{ userInfo.isAuthorized &&
<Grid container direction={'row'} justify={'center'} className={classes.formContainer}>
<Grid item xs={12} sm={12} md={12} lg={6} xl={5}>
<form className={classes.form}>
<FormControl className={classes.presetReportsInput}>
<InputLabel htmlFor="reports">Preset Reports</InputLabel>
<Select
value={this.state.report}
onChange={this.reportSelected}
>
<MenuItem value="">
<em>None</em>
</MenuItem>
{presetReports.getReportList().map(report => (
<MenuItem value={report.name} key={report.name}>
{report.name}
</MenuItem>
))}
</Select>
</FormControl>

{ (this.state.report === 'Inventory Snapshot' ||
this.state.report === 'Weekly Fill Rate' ||
this.state.report === 'Open Orders' ||
this.state.report === 'Weekly Shipments') &&
<div>
<Grid container spacing={8} direction={'row'}>
<Grid item>
<MuiPickersUtilsProvider utils={MomentUtils}>
<DatePicker
className={classes.datePicker}
margin="normal"
keyboard
format="DD/MM/YYYY"
disableFuture
autoOk
mask={value => (value ? [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/] : [])}
value={this.state.selectedDate}
onChange={this.handleDateChange}
disableOpenOnEnter
animateYearScrolling={false}
/>
</MuiPickersUtilsProvider>
</Grid>

<Grid item>
<TextField
id="Part #"
label="Part #"
value={this.state.itemNumber}
onChange={this.handleChange}
margin="normal"
/>
</Grid>
</Grid>

<Button variant="raised" color="primary" style={{ marginTop: 10 }}>
Search
</Button>
</div>
}

{ this.state.report === '' &&
<div>
<TextField
id="queryField"
label="Run a Query"
className={classes.queryField}
helperText=""
margin="normal"
multiline
rows="5"
/>

<Grid container direction={'row'} justify={'flex-end'}>
<Grid item>
<Button variant="raised" color="primary">
Export
</Button>
</Grid>
<Grid item>
<Button variant="raised" color="primary">
Save Query
</Button>
</Grid>
</Grid>
</div>
}
</form>
</Grid>

{ this.state.report === 'Inventory Snapshot' &&
<Grid container className={classes.table}>
<Grid item xs={12} sm={12} md={12} lg={12} xl={12}>
<InventoryReport />
</Grid>
</Grid>
}
</Grid>
}
</div>
)
}
}

const styles = {
dashboard: {},
formContainer: {
margin: 0,
width: '100%',
},
presetReportsInput: {
width: '100%',
margin: '20% 0 0 0',
},
queryField: {
width: '100%',
margin: '20% 0 0 0',
},
table: {
margin: '50px 0 10px 0',
},
datePicker: {
marginTop: 32,
},
}

const mapStateToProps = state => {
const { layout } = state
const { headerTitle } = layout
return {
headerTitle: headerTitle,
}
}

export default connect(mapStateToProps)(withStyles(styles)(Dashboard))

我正在 Chrome 中的 React devtools 中观察状态更新,输入字符和状态更新之间至少有 500 毫秒的延迟,为了加快打字速度,延迟时间要长得多。为什么 setState 这么慢?使该表单表现得像普通 Web 表单一样的解决方法是什么?

最佳答案

setState 本身并不慢,只有当您的渲染变得非常昂贵时,它才会开始引起问题。

需要考虑的一些事项是:

  • 您的主要组件看起来相当大,并且每次击键都会重新渲染,因此可能导致性能问题。尝试将其分解为更小的组件。
  • 确保在主组件的 render 方法中渲染的子组件不会进行不必要的重新渲染。 React Developer Toolswhy-did-you-render可以指出那些不必要的重新渲染。切换到 PureComponent、无状态组件或使用 shouldComponentUpdate可以提供帮助。
  • 虽然您无法避免在此处重新渲染(因为您的表单输入需要使用新的状态值重新渲染),但通过分解更小的组件,您可以考虑使用 shouldComponentUpdate让 React 知道组件的输出是否不受当前状态或 props 变化的影响,并避免不必要的重新渲染。
  • 如果您使用功能组件:
    • 使用useMemo防止重新计算昂贵的操作或组件,除非某些依赖项发生变化。
    • 使用useCallback返回回调的内存版本,以便依赖引用相等的子组件不会不必要地重新渲染
    • 使用React.memo如果您的功能组件在给定相同的 props 的情况下呈现相同的结果,以防止不必要的重新渲染。使用 React.memo 的第二个参数来自定义记忆化的行为(类似于 shouldComponentUpdate)
  • 切换到生产版本以获得更好的性能
  • 切换到uncontrolled components并让 DOM 自行处理输入组件(这是您描述的“正常 Web 表单”行为)。当您需要访问表单的值时,您可以使用 ref 来访问底层 DOM 节点并直接读取值。这应该消除调用 setState 并因此重新渲染的需要

关于reactjs - 响应输入 onChange 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50819260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com