有没有一种方法可以遍历由React构建的树?

9
我可以帮助您进行翻译。以下是需要翻译的内容:

我需要为一个HTML页面构建一个可视化编辑器。ReactJS似乎是一个不错的选择。目前,我遇到了以下问题:

我对我的数据进行了建模:

var Model = {
    title: 'Hello',
    description: 'Pellentesque eleifend urna ac purus tempus...',
    date: new Date().toString()
};

构建一个组件,该组件将其数据存储在上述结构中:

var App = React.createClass({
    getInitialState: function () {
        return {
            value: Model
        }
    },
    handleMouseEnter: function (event) {
        $(event.target).css('outline', '1px solid red').attr('contenteditable', true);
    },
    handleMouseLeave: function (event) {
        var t = $(event.target), v = this.state.value;
        t.css('outline', 'none').attr('contenteditable', false);
        v[t.attr('property')] = t.text();
        this.setState({value: v});
    },
    render: function () {
        var v = this.state.value;
        return (
            <div>
                <pre style={{whiteSpace: 'normal'}}>{JSON.stringify(this.state)}</pre>
                <h1 onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="title">{v.title}</h1>
                <p onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="description">{v.description}</p>
                <p onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="date">{v.date}</p>
            </div>
        );
    }
});

React.renderComponent(<App />, document.getElementById('app'));

在这种特定情况下它是起作用的。但我想摆脱onMouseEnteronMouseLeave属性,只保留property字段。像这样:
<pre style={{whiteSpace: 'normal'}}>{JSON.stringify(this.state)}</pre>
<h1 property="title">{v.title}</h1>
<p property="description">{v.description}</p>
<p property="date">{v.date}</p>

我考虑创建mixin。然后,在componentDidMount事件中,将处理程序附加到所有带有property属性的元素。但是我没有找到实现这一点的方法。
我的问题是:是否有办法遍历React构建的树?我注意到React Developer Tools(Chrome扩展程序)可以做到这一点。
类似问题:React.js组件创建父子关系并进行迭代

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - trekforever
1
@trekforever 不是一个好的解决方案。使用它我需要再建立一个模型——用于从中生成DOM节点的视图。http://jsfiddle.net/kb3gN/6684/ - vbarbarosh
1
在我看来,你似乎正在尝试做React可以为你完成的事情。 如果您想遍历此组件的所有_children_,只需使用children属性即可。 在我的意见中,更好的方法是在componentDidMount上使用mixin中的普通DOM方法,例如document.querySelectorAll('*[property]')(非jQuery ex)。 不知道选择器是否正确。 - Hulvej
1
你为什么要用jquery改变CSS,而不是在CSS文件中直接写h1.someClass:hover { outline: 1px solid red; }?此外,我听说contentEditable与React不兼容,你可能需要在继续之前阅读这里的内容https://dev59.com/VWEh5IYBdhLWcg3wNxEn#27255103。 - Andy
看一下高阶组件 https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e - T Mitchell
显示剩余3条评论
1个回答

0

所以你想要:

<h1 onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="title">{v.title}</h1>

作为

<h1 property="title">{v.title}</h1>

我会使用另一个组件来处理那个,它负责呈现那种特定类型的组件,就像redux-form一样。

实现你想要做的最简单的方法是:

class MyField extends Component {
  constructor(props) { 
    super(props); 
    this.handleMouseEnter = this.handleMouseEnter.bind(this); 
  }
  handleMouseEnter() { ... }
  render() {
    const { property, children } = this.props;
    if (property === 'title') {
      return (
        <h1 onMouseEnter...>{children}</h1>
      );
    }
  }
}

然后你可以在任何其他组件中这样调用它:

<MyField property="title">Stackoverflow</MyField>

一种更专业但也更困难的方法是使用Field的redux-form实现,甚至使用React.createElement生成HTML(就像我在上面的示例中使用if-else一样)。

如果您需要在外部访问其数据,则可以通过属性传递函数或将MyField组件连接到redux(redux-form也会这样做)。

我还会通过props传递任何特定的一次性样式,以便应用于您的MyField组件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接