I got my input who is filled by a value from my state.
我的输入是由我的州的一个值填充的。
<input id="flashVars" name="flashVars" type="text" value={settings.flashVarsValue} disabled={isDisabled} onChange={handleChange} />
Settings
is my state with Redux. When i put a value into my input, i must specify a onChange
function. This is my onChange function:
使用Redux设置我的状态。当我在输入中放入一个值时,我必须指定一个onChange函数。这是我的onChange函数:
handleFlashVarsChange(e) {
let { dispatch } = this.props;
dispatch( changeFlashVarsValue(e.target.value) );
}
It change the state value flashVarsValue
for the value of the input. But when i type in my input, it lags. I don't understand why i should call the dispatch each time i change the input value.
它将状态值flashVarsValue更改为输入值。但是当我输入我的输入时,它会滞后。我不明白为什么每次改变输入值都应该调用调度。
Is there any way who can give less lags?
有没有什么方法可以减少滞后?
My reducer:
import { ACTIONS } from '../utils/consts';
const initialState = {
...
flashVarsValue: '',
...
};
export function formSettings(state = initialState, action = '') {
switch (action.type) {
...
case ACTIONS.CHANGE_FLASHVARS_VALUE:
return Object.assign({}, state, {
flashVarsValue: action.data
});
default:
return state;
}
}
My action:
export function changeFlashVarsValue(data) {
return {
type: ACTIONS.CHANGE_FLASHVARS_VALUE,
data: data
}
}
Thank you
5 个解决方案
#1
9
I had a similar problem when I was editing a grid with a million rows, so what I did was to change the update logic, in your case handleChange to be called only on the event 'onBlur' instead of onChange. This will only trigger the update when you lose focus. But don't know if this would be a satisfactory solution for you..
当我编辑一个有一百万行的网格时,我遇到了类似的问题,所以我所做的就是更改更新逻辑,在你的情况下,handleChange仅在事件'onBlur'而不是onChange上调用。这只会在您失去焦点时触发更新。但不知道这对你来说是否是一个令人满意的解决方案..
#2
4
The answer for me was to use the shouldComponentUpdate lifecycle hook. This has already been given as an answer in a comment by Mike Boutin (about a year ago :) ), but an example might help the next visitor here.
我的答案是使用shouldComponentUpdate生命周期钩子。这已经在Mike Boutin的评论中得到了答案(大约一年前:)),但是一个例子可能会帮助下一位访客。
I had a similar problem, with the text input being lost, and slow and jumpy. I was using setState to update the formData in my onChange event.
我有一个类似的问题,文本输入丢失,缓慢和跳跃。我正在使用setState来更新onChange事件中的formData。
I found that the form was doing a complete re-render with every keypress, as the state had changed. So to stop this, I overrode the function:
我发现随着状态发生变化,表单正在对每个按键进行完全重新渲染。所以为了阻止这个,我重写了这个功能:
shouldComponentUpdate(nextProps, nextState) {
return this.state.formErrors !== nextState.formErrors);
}
I show an error notification panel on form submission with any new or changed validation errors, and that's the only time I need to re-render.
我在表单提交时显示错误通知面板,其中包含任何新的或更改的验证错误,这是我需要重新呈现的唯一时间。
If you have no child components, you could probably just set the form component's shouldComponentUpdate to always return false.
如果没有子组件,则可以将表单组件的shouldComponentUpdate设置为始终返回false。
#3
3
The issue here is possibly re-renders. You're passing in "settings" (your entire state) to your component containing the "input", and we don't know how the rest of your connected components are coupled to state. Check to see if as a result of the state object mutating, you're rerendering much more than just the input on every keystroke. The solution to this is to more directly pass in the specific parts of state you need from mapStateToProps (in this case, maybe only pass in "flashVarsValue" if that's all this component needs, and make sure other components aren't also passed the whole state) and use PureRenderMixin or Dan Abramov's https://github.com/gaearon/react-pure-render if you're using ES6 components to not re-render if your props haven't changed
这里的问题可能是重新渲染。您将“设置”(整个州)传递给包含“输入”的组件,我们不知道其他连接组件如何与状态耦合。检查是否由于状态对象发生变异,你重新渲染的不仅仅是每次击键时的输入。解决这个问题的方法是从mapStateToProps更直接地传递你需要的状态的特定部分(在这种情况下,如果这是所有这个组件需要的话,可能只传递“flashVarsValue”,并确保其他组件也不会传递给整个状态)并使用PureRenderMixin或Dan Abramov的https://github.com/gaearon/react-pure-render如果你使用ES6组件如果你的道具没有改变就不能重新渲染
#4
3
I know this is an old question, but if you want to fire onChange on a text input, you probably want to debounce your event. This thread does a good job breaking it down, but I think this would work for the op's example:
我知道这是一个老问题,但是如果你想在文本输入上触发更改,你可能想要去除你的事件。这个线程很好地分解了它,但我认为这适用于op的例子:
import debounce from 'debounce'
function debounceEventHandler(...args) {
const debounced = debounce(...args)
return function (e) {
e.persist();
return debounced(e);
}
}
const Container = React.createClass({
handleFlashVarsChange(e) {
let { dispatch } = this.props;
//basic redux stuff
this.props.changeFlashVarsValue(e.target.value));
},
render() {
const handleChange = debounceEventHandler(this.handleFlashVarsChange, 15);
return (
<input id="flashVars" onChange={handleChange} />
)
}
}
//...prep and return your redux container
#5
0
The answer is not to re-render your component on every key stroke, only if user stops typing in. Something like this:
答案不是在每次击键时重新渲染组件,只有当用户停止输入时才会这样。如下所示:
shouldComponentUpdate(nextProps, nextState) {
if (!textInputReRender)
return false;
else
return true;
}
onTextInputChange = (propName, propValue) => {
if (inputChangeTimerId)
clearTimeout(inputChangeTimerId);
inputChangeTimerId = setTimeout(() => {
inputChangeTimerId = null;
const newState = {};
textInputReRender = true;
newState[propName] = propValue;
this.setState(newState);
}, 500);
textInputReRender = false;
}
#1
9
I had a similar problem when I was editing a grid with a million rows, so what I did was to change the update logic, in your case handleChange to be called only on the event 'onBlur' instead of onChange. This will only trigger the update when you lose focus. But don't know if this would be a satisfactory solution for you..
当我编辑一个有一百万行的网格时,我遇到了类似的问题,所以我所做的就是更改更新逻辑,在你的情况下,handleChange仅在事件'onBlur'而不是onChange上调用。这只会在您失去焦点时触发更新。但不知道这对你来说是否是一个令人满意的解决方案..
#2
4
The answer for me was to use the shouldComponentUpdate lifecycle hook. This has already been given as an answer in a comment by Mike Boutin (about a year ago :) ), but an example might help the next visitor here.
我的答案是使用shouldComponentUpdate生命周期钩子。这已经在Mike Boutin的评论中得到了答案(大约一年前:)),但是一个例子可能会帮助下一位访客。
I had a similar problem, with the text input being lost, and slow and jumpy. I was using setState to update the formData in my onChange event.
我有一个类似的问题,文本输入丢失,缓慢和跳跃。我正在使用setState来更新onChange事件中的formData。
I found that the form was doing a complete re-render with every keypress, as the state had changed. So to stop this, I overrode the function:
我发现随着状态发生变化,表单正在对每个按键进行完全重新渲染。所以为了阻止这个,我重写了这个功能:
shouldComponentUpdate(nextProps, nextState) {
return this.state.formErrors !== nextState.formErrors);
}
I show an error notification panel on form submission with any new or changed validation errors, and that's the only time I need to re-render.
我在表单提交时显示错误通知面板,其中包含任何新的或更改的验证错误,这是我需要重新呈现的唯一时间。
If you have no child components, you could probably just set the form component's shouldComponentUpdate to always return false.
如果没有子组件,则可以将表单组件的shouldComponentUpdate设置为始终返回false。
#3
3
The issue here is possibly re-renders. You're passing in "settings" (your entire state) to your component containing the "input", and we don't know how the rest of your connected components are coupled to state. Check to see if as a result of the state object mutating, you're rerendering much more than just the input on every keystroke. The solution to this is to more directly pass in the specific parts of state you need from mapStateToProps (in this case, maybe only pass in "flashVarsValue" if that's all this component needs, and make sure other components aren't also passed the whole state) and use PureRenderMixin or Dan Abramov's https://github.com/gaearon/react-pure-render if you're using ES6 components to not re-render if your props haven't changed
这里的问题可能是重新渲染。您将“设置”(整个州)传递给包含“输入”的组件,我们不知道其他连接组件如何与状态耦合。检查是否由于状态对象发生变异,你重新渲染的不仅仅是每次击键时的输入。解决这个问题的方法是从mapStateToProps更直接地传递你需要的状态的特定部分(在这种情况下,如果这是所有这个组件需要的话,可能只传递“flashVarsValue”,并确保其他组件也不会传递给整个状态)并使用PureRenderMixin或Dan Abramov的https://github.com/gaearon/react-pure-render如果你使用ES6组件如果你的道具没有改变就不能重新渲染
#4
3
I know this is an old question, but if you want to fire onChange on a text input, you probably want to debounce your event. This thread does a good job breaking it down, but I think this would work for the op's example:
我知道这是一个老问题,但是如果你想在文本输入上触发更改,你可能想要去除你的事件。这个线程很好地分解了它,但我认为这适用于op的例子:
import debounce from 'debounce'
function debounceEventHandler(...args) {
const debounced = debounce(...args)
return function (e) {
e.persist();
return debounced(e);
}
}
const Container = React.createClass({
handleFlashVarsChange(e) {
let { dispatch } = this.props;
//basic redux stuff
this.props.changeFlashVarsValue(e.target.value));
},
render() {
const handleChange = debounceEventHandler(this.handleFlashVarsChange, 15);
return (
<input id="flashVars" onChange={handleChange} />
)
}
}
//...prep and return your redux container
#5
0
The answer is not to re-render your component on every key stroke, only if user stops typing in. Something like this:
答案不是在每次击键时重新渲染组件,只有当用户停止输入时才会这样。如下所示:
shouldComponentUpdate(nextProps, nextState) {
if (!textInputReRender)
return false;
else
return true;
}
onTextInputChange = (propName, propValue) => {
if (inputChangeTimerId)
clearTimeout(inputChangeTimerId);
inputChangeTimerId = setTimeout(() => {
inputChangeTimerId = null;
const newState = {};
textInputReRender = true;
newState[propName] = propValue;
this.setState(newState);
}, 500);
textInputReRender = false;
}