Javascript 对高阶组件作出反应,向呈现的JSX添加自定义属性
我正在尝试编写一个React高阶组件,以便在WrappedMonet的视图中添加一个自定义属性“test_id”,我需要这个自动生成的属性来稍后进行一些UI测试。但我还没有找到实现这一目标的方法Javascript 对高阶组件作出反应,向呈现的JSX添加自定义属性,javascript,reactjs,Javascript,Reactjs,我正在尝试编写一个React高阶组件,以便在WrappedMonet的视图中添加一个自定义属性“test_id”,我需要这个自动生成的属性来稍后进行一些UI测试。但我还没有找到实现这一目标的方法 import React, {Component, PropTypes} from "react"; const wrapTestableComponent = (ComponentToWrap) => { class TestableComponent extends Component {
import React, {Component, PropTypes} from "react";
const wrapTestableComponent = (ComponentToWrap) => {
class TestableComponent extends Component {
constructor(props){
super(props);
}
render() {
return <ComponentToWrap {...this.props} test_id={this.props.test_id} />;
}
}
TestableComponent.propTypes = {
test_id: PropTypes.string.isRequired,
}
return TestableComponent
}
export default wrapTestableComponent;
import React,{Component,PropTypes}来自“React”;
常量wrapTestableComponent=(ComponentToWrap)=>{
类TestableComponent扩展组件{
建造师(道具){
超级(道具);
}
render(){
返回;
}
}
TestableComponent.propTypes={
测试id:PropTypes.string.isRequired,
}
返回可测试组件
}
导出默认wrapTestableComponent;
我也尝试了下面的版本,但我得到了错误:uncaughttypeerror:无法添加属性test\u id,对象不可扩展
import React, {Component, PropTypes} from "react";
const wrapTestableComponent = (ComponentToWrap) => {
class TestableComponent extends Component {
constructor(props){
super(props);
}
render() {
var wrappedComponentView = <ComponentToWrap {...this.props} />;
wrappedComponentView.test_id = this.props.test_id;
return <ComponentToWrap {...this.props} />;
}
}
TestableComponent.propTypes = {
test_id: PropTypes.string.isRequired,
}
return TestableComponent
}
export default wrapTestableComponent;
import React,{Component,PropTypes}来自“React”;
常量wrapTestableComponent=(ComponentToWrap)=>{
类TestableComponent扩展组件{
建造师(道具){
超级(道具);
}
render(){
var wrappedComponentView=;
wrappedComponentView.test\u id=this.props.test\u id;
返回;
}
}
TestableComponent.propTypes={
测试id:PropTypes.string.isRequired,
}
返回可测试组件
}
导出默认wrapTestableComponent;
编辑
根据我们下面讨论的评论,我之前误解了这个问题,因此修改了我的答案
你在中使用的方式应该是做你想做的事情的最佳方式
我尝试创建一个返回React.createElement()
的函数来创建副本,并为componentToRap
分配了额外的道具,但由于两个主要原因失败了
类型
const wrapTestableComponent=(componentToRap)=>{
类TestableComponent扩展了React.Component{
componentDidMount(){
ReactDOM.findDOMNode(this.wrappedRef.setAttribute('test\u id',this.props.test\u id));
}
render(){
返回{this.wrappedRef=this;}}
/>;
}
}
TestableComponent.propTypes={
测试id:React.PropTypes.string.isRequired,
}
返回可测试组件
}
常量TestComp=(道具)=>(这是TestComp)
const NewComponent=wrapTestableComponent(TestComp)
ReactDOM.render(,document.getElementById('View'))
我想这就是你想要找到的
ref
可以为您带来所有的魔力。事实上,我没有任何其他的想法如何添加自定义组件
导出函数SelectWrapper(选择){
返回类包装器扩展组件{
componentDidMount(){
var元素=ReactDOM.findDOMNode(this.refs.test);
setAttribute('custom-attribute','some value');
}
...
render(){
返回
}
}
}
它给了你什么?在componentToRap
istest\u id
undefined/null中,您的第一个示例应该可以正常工作。如何应用HOC?还要注意,两个示例中的noop构造函数都可以省略。下面是如何使用HOC类MyComponent扩展组件{constructor(props){super(props);}render(){return({this.props.in});}}}导出默认wrapTestableComponent(MyComponent)代码>@Hakim,你核对过我的答案了吗?或者您找到了根本原因了吗?Hi@Lee使用HOC的主要目的是在封装组件的dom中自动注入测试id。修改后的代码没有提供解决方案,因为他让封装的组件在其dom中添加测试idconst TestComp=(props)=>(这里是测试id=>{props.test\u id})
@Hakim,部分这里是测试id=>{props.test\u id}
正在证明它确实获得了测试id
,并由两行WrappedComponent开始
和WrappedComponent结束
包装。你可以这样做你的组件顺便说一下,你可以查看我的第一个代码片段,我不知道你的拼写是否正确。但是您可以看到,您只需将id
传递给包装组件NewComponent
,就可以在TestComp
中获得test\u id
。下面是我如何实现在包装组件的dom中注入test\u id属性的,但我不喜欢使用findDOMNode函数。您有其他方法实现这一点吗没有调用API?@Hakim我之前误解了你想要什么。在我做了一些研究之后。您当前使用的方法应该是正确的。谢谢,但我不想使用findDOMNode函数,因为它查询真实的DOM以查找包装的组件,因此性能非常昂贵。facebook官方文档不鼓励使用facebook.github.io/react/docs/react dom.html#finddomnode这一功能,顺便说一句,在较新版本的github.com/yannickcr/eslint-plugin-react/issues/678中可能会被弃用。我确信有一种正确的方法可以在安装包装组件之前注入“test_id”属性,但我仍然难以找到它……此外,如果ComponentToRap是一个不支持refs的功能/纯/无状态组件,那么这种方法将不起作用@哈基姆:这是一种解决问题的方法。您没有提到是否要使用refs
(功能/纯/无状态组件也是如此)。如果你打算描述整个逻辑,我们可能会尝试用另一种方式来解决它。我一开始不知道refs可以用来解决我的问题,因为我知道我正在寻找一种解决方法,以避免使用findDOMNode,Facebook似乎不推荐使用findDOMNode。HOC将用于包装我的应用程序的所有组件(非常复杂的一个),我担心findDOMNode的p上会有坏的impiact
export function SelectWrapper(Select){
return class Wrapper extends Component {
componentDidMount(){
var element = ReactDOM.findDOMNode(this.refs.test);
element.setAttribute('custom-attribute', 'some value');
}
...
render(){
return <Select {...this.props} ref='test'/>
}
}
}