53

我的输入被我所在州的一个值填充。

<input id="flashVars" name="flashVars" type="text" value={settings.flashVarsValue} disabled={isDisabled} onChange={handleChange} />

Settings是我对 Redux 的状态。当我在输入中输入一个值时,我必须指定一个onChange函数。这是我的 onChange 函数:

handleFlashVarsChange(e) {
  let { dispatch } = this.props;

  dispatch( changeFlashVarsValue(e.target.value) );
}

它更改flashVarsValue输入值的状态值。但是当我输入我的输入时,它会滞后。我不明白为什么每次更改输入值时都应该调用调度。

有什么办法可以减少延迟?

我的减速机:

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;
  }
}

我的行动:

export function changeFlashVarsValue(data) {
  return {
    type: ACTIONS.CHANGE_FLASHVARS_VALUE,
    data: data
  }
}

谢谢

4

7 回答 7

28

我在编辑具有一百万行的网格时遇到了类似的问题,所以我所做的是更改更新逻辑,在您的情况下handleChange,仅在事件onBlur而不是onChange. 这只会在您失去焦点时触发更新。但不知道这是否对您来说是一个令人满意的解决方案。

于 2015-11-07T20:48:42.890 回答
5

我的答案是使用 shouldComponentUpdate 生命周期钩子。这已经在 Mike Boutin 的评论中给出了答案(大约一年前:)),但是一个例子可能会帮助下一位访问者。

我有一个类似的问题,文本输入丢失,缓慢而跳跃。我在我的 onChange 事件中使用 setState 来更新 formData。

我发现表单在每次按键时都会进行完整的重新渲染,因为状态发生了变化。所以为了阻止这个,我覆盖了这个函数:

shouldComponentUpdate(nextProps, nextState) {
   return this.state.formErrors !== nextState.formErrors);
}

我在表单提交时显示一个错误通知面板,其中包含任何新的或更改的验证错误,这是我唯一需要重新呈现的时间。

如果您没有子组件,您可能只需将表单组件的 shouldComponentUpdate 设置为始终返回 false。

于 2017-01-04T10:44:31.497 回答
5

我知道这是一个老问题,但如果你想在文本输入上触发 onChange,你可能想要去抖动你的事件。该线程很好地将其分解,但我认为这适用于操作的示例:

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
于 2017-05-26T15:01:11.443 回答
4

这里的问题可能是重新渲染。您将“设置”(您的整个状态)传递给包含“输入”的组件,我们不知道其余连接的组件如何与状态耦合。检查是否由于状态对象的变化,您重新渲染的不仅仅是每次击键时的输入。对此的解决方案是更直接地从 mapStateToProps 传递您需要的特定状态部分(在这种情况下,如果这就是该组件所需的全部,则可能只传递“flashVarsValue”,并确保其他组件也不会全部传递state) 并使用 PureRenderMixin 或 Dan Abramov 的https://github.com/gaearon/react-pure-render如果您使用 ES6 组件,如果您的道具没有改变,则不重新渲染

于 2016-07-07T14:14:20.967 回答
3

答案是不要在每次击键时重新渲染组件,只有在用户停止输入时才重新渲染组件。像这样:

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;
}
于 2018-09-11T09:35:16.227 回答
1

onChangeText改为使用

import { TextInput, View} from "react-native";  
import { connect } from "react-redux"; 
import React, { Component, useState } from "react";

function SearchTextInput(props) {
  const { keyword = "", setKeyword } = props; 
  return (
     <TextInput
       style={styles.searchInputText}
       placeholder={"placeholder here"}
       value={keyword}
       onChangeText={setKeyword(t)}
     />
  );
}

const mapStateToProps = state => {
  return {
    keyword: state.search.keyword,
    search: state.search
  };
};
const mapDispatchToProps = dispatch => ({
  setKeyword: payload => dispatch(({type:'updateSearchText', keyword: payload }))
});
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SearchTextInput);
于 2019-08-25T21:54:06.173 回答
0

当您有一个复杂的页面时,这个问题很常见,需要始终重新渲染您更新状态。所以你可以感觉到打字的时候很慢。

我找到了一个解决方案:组件运行的react生命周期。因此,您可以在调用 onBlur 之后创建其他组件并管理您的事件,例如 onChange,这是由 props 为他传递的。它对我有用:

import React, {Fragment, useState, useEffect} from 'react';
import TextField from '@material-ui/core/TextField';


export function InputText(props) {
  const [value, setValue] = useState("");
  const {onBlur = (e) => {console.log(e)}, name='name', defaultValue= 'Default', type='text', label='Label'} = props

  useEffect(() => {

    // console.log(value);
  })

  return (
      <label>
        <TextField 
          name={name} 
          label={label}  
          onBlur={e => onBlur(e)}
          type={type}
          value={value}
          onChange={e => setValue(e.target.value)}
        />
      </label>
  );
}


class Sample extends React.Component {
    handleBlurInput = e => {        
         this.setState({ [e.target.name]: e.target.value });
    };
  render() {
    return (
    <InputText name="nome" label="Label Sample" defaultValue={this.state.nome} onBlur={this.handleBlurInput.bind(this)} />

    // Complex app ....
    );
  }
}
于 2020-02-05T14:00:02.523 回答