有没有办法遍历由React构建的树?

vba*_*osh 9 javascript reactjs

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

我模拟了我的数据:

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

并构建了将其数据存储在上述结构中的组件:

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'));
Run Code Online (Sandbox Code Playgroud)

在那种特殊情况下它起作用.但我想摆脱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>
Run Code Online (Sandbox Code Playgroud)

我想过创建mixin.然后,在inside componentDidMount事件中,将处理程序附加到具有property属性的所有元素.但我发现无法实现这一目标.

我的问题是:有没有办法遍历由React构建的树?我注意到React Developer Tools(Chrome扩展程序)可以做到这一点.

类似问题:React.js组件创建父子关系和迭代

zur*_*fyx 0

所以你要:

<h1 onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} property="title">{v.title}</h1>
Run Code Online (Sandbox Code Playgroud)

作为

<h1 property="title">{v.title}</h1>
Run Code Online (Sandbox Code Playgroud)

我会使用另一个Component,它负责特定类型组件的渲染,就像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>
      );
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

<MyField property="title">Stackoverflow</MyField>
Run Code Online (Sandbox Code Playgroud)

更专业但也更困难的方法是Field的 redux 形式实现,他们甚至使用React.createElement来生成 HTML(我在上面的示例中使用 if-else 所做的)。

如果您需要访问其外部的任何数据,可以通过属性向其传递一个函数,或者将该MyField组件连接到 redux(redux-form 也可以这样做)。

我还会传递您想要应用于组件的任何特定一次性样式的 props MyField