更新后,反应输入光标移动到结尾

时间:2017-07-19 19:42:50

标签: reactjs redux

当我更新输入字段中的值时,光标移动到字段的末尾,但我希望它保持原样。可能导致这个问题的原因是什么?

window.location.href = window.location.href;

其中Input是文本输入字段的组件,getOnChange是:

<Input
  type="text"
  placeholder="test
  name="test"
  onChange={getOnChange(index)}
  value={testVal}/>

然后将其转移到父组件,在那里我调度以通过Redux更新状态。我可以看到状态正在更新,但问题是光标没有停留在位,并且总是移动到文本的末尾

6 个答案:

答案 0 :(得分:1)

如果光标跳到该字段的末尾,通常意味着您的组件正在重新安装。发生这种情况的原因可能是,父项中某处的值每次更新时关键属性都发生了更改,或者组件树中发生了更改。不看更多代码就很难分辨。防止重新安装,光标应停止跳跃。

使用此效果跟踪安装/卸载

useEffect(() => {
   console.log('mounted');

   return () => { 
       console.log('unmounted')
   }
}, []);

答案 1 :(得分:1)

我遇到了同样的问题,这是由于 2 个连续的 setState 语句造成的。更改为单个 setState 解决了该问题。可能对某人有帮助。

修复前的代码:

const onChange = (val) => {
 // Some processing here
 this.setState({firstName: val}, () => {
  this.updateParentNode(val)
 })
}

const updateParentNode = (val) => {
  this.setState({selectedPerson: {firstName: val}})
}

修复后的代码

const onChange = (val) => {
// Some processing here
  this.updateParentNode(val)
}

const updateParentNode = (val) => {
  this.setState({selectedPerson: {firstName: val}, firstName: val})
}

答案 2 :(得分:0)

这是受控组件设计模式的缺点。我已经面对这个问题很长时间了,并且一直忍受着。但是有一种想法,我想在业余时间尝试,但最终还是没有尝试过。也许继续我的想法可以帮助您找到所需的解决方案?

<Input
  type="text"
  placeholder="test
  name="test"
  onChange={getOnChange(index)}
  value={testVal}
/>


// From props.onChangeTest
const onChangeTest = (event, index) => {
  // TODO: Memorize the position of the cursor
  this.setState({ testVal: event.target.value })

  // Because setState is asynchronous
  setTimeout(() => {
    // TODO:
    // Programmatically move cursor back to the saved position
    // BUT it must increase/decrease based on number of characters added/removed
    // At the same time considering if the characters were removed before or after the position

    // Theoretically do-able, but it's very mind-blowing
    // to come up with a solution that can actually 'nail it'
  }, 0)
}


★如果这花了太多时间,而您只想完成工作并发布应用程序,则可能要考虑使用不受控制的组件设计模式。

答案 3 :(得分:0)

您有两个选择。

  1. 将其设置为不受控制的输入(以后无法更改输入值)

  2. 使其成为适当控制的输入

这里缺少代码,所以我不能说问题出在哪里。 setState不是问题:https://reactjs.org/docs/forms.html#controlled-components

如果在回调中使用setState,React应该保留光标位置。

您能举一个更完整的例子吗? testVal是从组件外部操纵的属性吗?

答案 4 :(得分:0)

我建议使用钩子解决此问题

const Component = ({ onChange }) => {
  const [text, setText] = useState("");
  const isInitialRun = useRef(false);

  useEffect(() => {
     if (isInitialRun.current) {
        onChange(text);
     } else {
        isInitialRun.current = true;
     }
  }, [text]);

  // or if you want to have a delay

  useEffect(() => {
     if (isInitialRun.current) {
         const timeoutId = setTimeout(() => onChange(text), 500);
         return () => clearTimeout(timeoutId);
    } else {
         isInitialRun.current = true;
    }
  }, [text])

  return (
    <Input
        type="text"
        placeholder="test
        name="test"
        onChange={setText}
        value={text}/>
 );
}

为防止进行初始呼叫,请在未进行任何更改的情况下使用isInitialRun

答案 5 :(得分:-1)

当您通过代码动态更新输入值时,输入上的光标将被推到末尾,这似乎是您在做的,因为我可以看到value={testVal}:)

这是使用输入掩码的字段上的常见问题!