【发布时间】:2021-12-02 07:46:21
【问题描述】:
我正在使用 redux 来更新我的应用程序中的状态,我有一个关于用于设置组件状态的最佳事件的问题。
当我更改描述然后点击保存按钮后,我希望状态将被更新并保存在数据库中。
所以我尝试在事件onBlur 中设置状态,但如果我们仍然专注于描述,则在单击保存按钮之前它不会保存。
所以我想使用onMouseMove,但它仅在鼠标位于组件位置时才识别鼠标。
最后一个想法是使用onKeyPress,但它看起来更新太多了。而且我认为也许有更好的事件甚至一些生命周期可以在其中使用。
描述组件:
import React from 'react';
import {
FormControl
} from 'react-bootstrap';
import _ from 'lodash';
let createReactClass = require('create-react-class');
import PropTypes from 'prop-types';
/**
* Helper class to limit re-render of components when editing title.
* Rendered as a simple text while not focused / mouse over.
*/
const EditableLabel = createReactClass({
propTypes: {
value: PropTypes.any,
onChange: PropTypes.func,
editMode: PropTypes.oneOf(['always', 'click', 'double-click']),
validateFunc: PropTypes.func
},
__inputRef: null,
getDefaultProps() {
return {
editMode: 'click'
}
},
getInitialState() {
return {
value: this.props.value
};
},
componentWillReceiveProps(newProps) {
if (newProps.value !== this.props.value) {
this.setState({value: newProps.value});
}
},
_onChange(oldValue,newValue) {
if(this.props.validateFunc && !this.props.validateFunc(newValue)) {
// input is not valid
this.setState({value: oldValue})
} else {
// input is valid or no validateFunc defined
if (this.props.onChange) {
if (oldValue !== newValue) {
this.props.onChange(newValue)
}
}
}
},
render() {
let props = _.omit(this.props, ['value', 'onChange', 'editMode','validateFunc','activeHref','activeKey']);
let className = undefined;
if (this.props.editMode === 'click') {
className = "hover-border-visible";
} else if (this.props.editMode === 'double-click') {
// not implemented yet
}
return (
<FormControl inputRef = {(ref) => {this.__inputRef = ref;}}
className={className}
{...props}
type="text" value={this.state.value}
onChange={(ev) => this.setState({value: ev.target.value})}
onBlur={(ev) => {
this._onChange(this.props.value,ev.target.value)
}}
onMouseMove={(ev) => {
this._onChange(this.props.value,ev.target.value)
}}
onFocus={(ev) => ev.target.setSelectionRange(0, ev.target.value.length)}
// onKeyPress={(ev) => {
// this._onChange(this.props.value, ev.target.value)
// }}
/>
);
}
});
export default EditableLabel;
【问题讨论】:
-
您使用的是旧代码库吗?除了
render之外,没有一个生命周期方法被使用得太多了。使用onChange事件处理程序有什么问题?所有其他人的用例是什么?我会说这似乎是过度设计,但其他事件处理程序真的没有意义。相关的 redux 代码在哪里?为什么不调度操作来更新商店? -
表单状态应该直接进入 redux(来自 onchange 事件),而不是存储在本地。这就是 redux 的全部意义,将所有内容保存在本地,然后尝试在特定时间以某种方式同步,这违背了目的。
-
嘿,Drew Reese,因为 onChange 和 onPress 完全一样,我担心太多的变化会损害应用程序的速度。
-
您是否发现任何性能问题?您是否进行过任何性能审计来跟踪性能问题/瓶颈? React 开箱即用地进行了很好的优化。 Redux(reducer 函数)通常也能很好地工作。不要过早优化。