繁体   English   中英

从 JavaScript 或 JQuery 设置 React 输入字段值

[英]Set React Input Field Value from JavaScript or JQuery

如何以编程方式设置由 React 生成的输入字段的值,无论是使用 vanilla JS 还是 JQuery?

我尝试了以下方法,但似乎没有任何效果。

$(obj).val('abc');
$(obj).attr('value', 'abc');
$(obj).keydown();
$(obj).keypress();
$(obj).keyup();
$(obj).blur();
$(obj).change();
$(obj).focus();

我也试着来模拟keyPress (如建议在这里)事件,但它似乎并没有工作或者没有。

simulateKeyPresses (characters, ...args) {
  for (let i = 0; i < characters.length; i++) {
    this.simulate('keyPress', extend({
      which: characters.charCodeAt(i),
      key: characters[i],
      keyCode: characters.charCodeAt(i)
    }, args));
  }
}

在所有的答案中,经过大量的谷歌搜索,我发现这是有效的

function changeValue(input,value){

    var nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLInputElement.prototype,
      "value"
    ).set;
    nativeInputValueSetter.call(input, value);

    var inputEvent = new Event("input", { bubbles: true });
    input.dispatchEvent(inputEvent);
}

我们正在使用 window.HTMLInputElement.prototype,即 HTMLInputElement。 一个界面,提供用于操作输入元素的选项、布局和呈现的特殊属性和方法。

然后我们将使用 Object.getOwnPropertyDescriptor() 方法来设置输入值。 最后,我们将在输入上调度更改事件以使用 React onChange 进行模拟

这里是这个答案的详细解释: https : //hustle.bizongo.in/simulate-react-on-change-on-Controlled-components-baa336920e04

正如在 模拟部分的 react test utils 文档中所展示的那样,您可以看到他们所做的基本上是更改 DOM 节点值,然后触发输入事件。

你可以做的是类似下面的事情,用你的输入 DOM 元素和新值调用它。

const changeValue = (element, value) => {
  const event = new Event('input', { bubbles: true })
  element.value = value
  element.dispatchEvent(event)
}

不过,这取决于您如何定义组件,例如,如果您期望输入按键,则必须分派匹配的事件。

这是一个经过充分测试的解决方案,适用于 IE11 以及其他浏览器。 我猜是 createNewEvent 将这个解决方案与其他解决方案区分开来。 setReactValue方法还返回更改后的值。

function setReactValue(element, value) {
  let lastValue = element.value;
  element.value = value;
  let event = createNewEvent("input", element);
  event.simulated = true;
  let tracker = element._valueTracker;
  if (tracker) {
    tracker.setValue(lastValue);
    element.dispatchEvent(event);
  }
  return lastValue;
}

function createNewEvent(eventName, element) {
    let event;
    if (typeof(Event) === 'function') {
        event = new Event(eventName, {target: element, bubbles:true});
    } else {
        event = document.createEvent('Event');
        event.initEvent(eventName, true, true);
        element.addEventListener(eventName, function(e) {
          e.target = element;
        });
    }
    return event;
}

根据这个答案,您可以从 dom 获取 react 实例。

假设obj是一个 dom 元素。

function findReact(dom) {// from https://stackoverflow.com/a/39165137/4831179
    for (var key in dom) {
        if (key.startsWith("__reactInternalInstance$")) {
            var compInternals = dom[key]._currentElement;
            var compWrapper = compInternals._owner;
            var comp = compWrapper._instance;
            return comp;
        }
    }
    return null;
};

var instance = findReact(obj);

console.log(instance.state);//try to modify the form and check what's here

instance.setState({
//the state name from the previous step
});

instance.submit();//something like this

这将取决于浏览器,但对于文本输入, onChange调用正在侦听input事件

element.value = 'new value';
var event = new Event('input', { bubbles: true });
element.dispatchEvent(event);

您可以通过使用 ReactDOM( https://facebook.github.io/react/docs/react-dom.html ) 和 Jquery 来实现这一点,像这样操作不是很常见,但它有效:

var ctx = this; 
//Save the context of your class to the variable ctx, since inside $/Jquery the this is a reference to $/Jquery itself.
$(ReactDOM.findDOMNode(ctx.refs.myInput)).val('abc');

你的输入必须有一个 ref 属性才能让 React 找到它:

<input type="text"
  className="form-control"
  ref="myInput"
  placeholder="text"
/>

我在另一个使用 JQuery 构建的框架中使用 React 时遇到了同样的问题。 但就我而言,我只需要更改一个字段。 请检查是否适合您:

import React, { useEffect, useRef } from 'react';

const Exemple = () => {
  const [value, setValue] = useState();
  const inputRef = useRef(null);

  useEffect(() => {
    const myInputRef = inputRef.current;
    myInputRef.onchange = e => setValue(e.target.value)
  }, [])
  
  return (
    <div>
      <input ref={inputRef} id={my_id} />
    </div>
  );
}

export default Exemple;

您可以使用状态直接更新文本字段的值。

设状态中文本输入的值为:

state = {
   textInputValue: ""
};

这就是你在 React 中定义文本输入的方式

<input type="text"
  className="form-control"
  name="my-text-input"
  placeholder="text"
  value={this.state.textInputValue}
  onChange={this.onTextInputChange}
/>

一旦你定义了你的文本输入,你可以通过改变你的状态来更新你的文本输入的值,比如在你的反应组件中this.setState({textInputValue: 'MyText'}) 之后,您通常可以使用更新文本字段的值

onTextInputChange(event) {
    let newText = event.target.value;
    return this.setState({textInputValue: newText});
}

不知道你遇到什么样的场景。 由于 React 创建和维护自己的虚拟 DOM,因此您无法从 React 外部使用 Jquery 或 Javascript 操作 DOM 元素。 但是,如果您需要从外部获取数据,请在 React 组件中使用 componentWillMount() 编写从所需数据源获取数据并将其设置为 TextInput 状态的代码

componentWillMount() {
    // Code to get your data into variable 'defaultTextValue'
    this.setState({textInputValue: defaultTextValue});
}

尝试重新分配整个 html 内容,如

 $("html").on("DOMNodeInserted DOMNodeRemoved change", "body", function(){
     $("body").html($("body").html()); 
 });

 // or call a simple function with $("body").html($("body").html());

我这样做是为了在原始代码注入后重新分配 html 并在 jquery 中的 svg 标签上再次应用事件......也许这也适用于这种情况......

在事件上尝试 .on() 方法。

我已经制作了一个代码笔,其中包含一个我认为 Dani Akash 想说的工作示例。 重要的是要知道,在 React 中, setState()会导致组件重新渲染,因此在我的示例中,将新状态作为 prop 传递给子组件。

https://codepen.io/tskjetne/pen/mmOvmb?editors=1010

  1. 首先我渲染我创建的Parent组件。 父组件包含一个按钮和另一个我创建的 React 组件InputWithButton
  2. 首先调用Parent构造函数,将Parent组件状态设置为对象{value: "initial value"}
  3. setValueInParent是一个单击处理程序,我绑定到Parent组件中的按钮。 它设置导致重新渲染的Parent组件状态。
  4. Parent组件将其state.value作为 prop 传递给InputWithButton组件。
  5. InputWithButton组件与父组件非常相似。 虽然,在构造函数中,它将状态值设置为从父级传入的值 prop。
  6. 除此之外, InputWithButton组件的工作方式与Parent组件大致相同。

这使您可以通过在输入字段中键入内容、单击与输入字段相同的组件中的按钮并从父级传入一个新值作为 prop 来更改输入值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM