简体   繁体   English

是否可以编写脚本以将道具注入React组件?

[英]Is it possible to write a script to inject props on a React component?

So this is a little crazy. 所以这有点疯狂。 There's a web app that I use that is built with React, which has made certain design decisions that I disagree with. 我使用的是一个由React构建的Web应用程序,它做出了一些我不同意的设计决策。

Luckily, the design is actually simple to change exactly the way I want. 幸运的是,设计实际上很容易按照我想要的方式进行更改。 I can just open the Chrome React devtools and change the props assigned to a specific component. 我可以打开Chrome React devtools并更改分配给特定组件的道具。

But I don't want to manually do this every time, that's not worth it. 但是我不想每次都手动执行此操作,这不值得。 I want to write a (super hacky) personal bit of javascript that I can inject into the page, which modifies the props being passed to this component. 我想编写一个(超级hacky)个人javascript代码,可以将其注入页面中,从而修改传递给该组件的道具。

Wondering if anyone knows a simple hack to inject props from outside of React. 想知道是否有人知道有一个简单的技巧可以从React外部注入道具。 Perhaps it's possible to hook into whatever mechanism React uses to respond to the devtools? 也许有可能加入React用于响应devtools的任何机制?

I've found the following code to generally work with the latest version of React. 我发现以下代码通常可以与最新版本的React一起使用。

function updateProps(domElement, newProps) {
  var keys = Object.keys(domElement);
  var instanceKey = keys.filter(prop =>
    /__reactInternalInstance/.test(prop)
  )[0];
  var instance = domElement[instanceKey];

  for (var prop in newProps) {
    if (newProps.hasOwnProperty(prop)) {
      instance.return.stateNode.props[prop] = newProps[prop];
    }
  }
  instance.return.stateNode.updater.enqueueForceUpdate(
    instance.return.stateNode
  );
}

As an example, you can navigate here https://ahfarmer.github.io/calculator/ and paste all of the code below into the Chrome DevTools console: 例如,您可以在此处浏览https://ahfarmer.github.io/calculator/并将以下所有代码粘贴到Chrome DevTools控制台中:

function updateProps(domElement, newProps) {
  var keys = Object.keys(domElement);
  var instanceKey = keys.filter(prop =>
    /__reactInternalInstance/.test(prop)
  )[0];
  var instance = domElement[instanceKey];

  for (var prop in newProps) {
    if (newProps.hasOwnProperty(prop)) {
      instance.return.stateNode.props[prop] = newProps[prop];
    }
  }
  instance.return.stateNode.updater.enqueueForceUpdate(
    instance.return.stateNode
  );
}

updateProps(document.getElementById("root").childNodes[0].childNodes[0], { value: 9000 });

The calculator's value will be programmatically updated to 9000. 计算器的值将以编程方式更新为9000。

As a rule of thumb, you want to target the topmost DOM element being rendered in the React component. 根据经验,您希望定位在React组件中呈现的最顶层DOM元素。

// React component
class Application extends React.Component {
  render() {
    return <div id="myapp">Hello {this.props.name}</div>;
  }
}

// Your javascript code
updateProps(document.getElementById("myapp"), { name: 'Jane' }));

You may need some additional hacking to make this work with your specific use case. 您可能需要一些额外的技巧才能使它与您的特定用例一​​起使用。 It's just a matter of figuring out which React internal properties to manipulate. 只是确定要操纵哪些React内部属性的问题。

Also you can use jQuery to make targeting the elements easier. 您也可以使用jQuery使元素定位更容易。

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

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