所有React(或Flux / React)应用程序是否必须具有一些顶级App组件?

时间:2015-12-22 08:38:18

标签: reactjs reactjs-flux

我有一个使用React的小应用程序。我只有两个React组件:MessageBoxSearchBoxMessageBox呈现消息列表,而SearchBox仅呈现没有任何功能的<input type="text" placeholder="Say something">元素,例如onClick或smth。 Thay就像那样简单。

以下是MessageBox组件:

var MessageBox = React.createClass({
    getInitialState: function() {
        return {
            data: []
        }
    },
    componentWillMount: function() { },
    componentDidMount: function() {
        this.setState({
            data: this.props.data
        });
    },
    componentWillUnmount: function(a, b) { },
    render: function() {
        return (
            <div>
                <MessagList data={this.state.data} />
            </div>
        );
    }
});

var MessagList = React.createClass({
    componentWillMount: function () { },
    componentDidMount: function() { },
    componentWillUnmount: function() { },
    render: function() {
        var data = this.props.data || [];
        var messages = data.map(function(item, i) {
            return <Message index={i} key={i} text={item.text} />
        })
        return (
            <ul className="msgUl">
                {messages}
            </ul>
        );
    }
});

var Message = React.createClass({
    render: function() {
        return (
            <li className="message">
                {this.props.text}
            </li>
        );
    }
});

这是SearchBox组件:

var SearchBox = React.createClass({
    render: function() {
        return (
            <div className="searchbox">
                <input type="text" placeholder="Say something" />
            </div>
        );
    }
});

所以,这里的要点是它们绝对与DOM分开,因为它们不是具有所有标记且使用我的MessageBox和{{1}的全局React组件的子代。作为孩子。

SearchBox

我将我的组件渲染到我想要的任意DOM元素中。他们不是某些App的孩子:

<html>
    <head>
    <body>
        <SearchBox />
        <MessageBox data={some_data} />

现在我查看示例Flux examplesreact-router示例。我想知道,他们都练习了一个代表整个页面标记的顶级 ReactDOM.render( <MessageBox data={window.data} />, document.getElementById('message-box') ); ReactDOM.render( <SearchBox />, document.getElementById('searchbox') ); 组件,如下所示:

App

React普及的video也涉及全球App组件。

我的问题是。这是他们的&#34;最佳实践&#34;使用React?我是否必须使用我的标记中的React从上到下完全使用React,从// flux-react-boilerplate var React = require('react'); var App = require('./App.js'); React.render(<App/>, document.body); // <== append right in body // react-router render(( <Router> <Route path="/" component={App}> <Route path="about" component={About}/> <Route path="users" component={Users}> <Route path="/user/:userId" component={User}/> </Route> <Route path="*" component={NoMatch}/> </Route> </Router> ), document.body) // <== append right in body <html>?在我的情况下,我可以只使用两个独立的组件来使用Flux吗?

1 个答案:

答案 0 :(得分:2)

你按照自己的方式做得很好。没有一个固有的原因,你应该总是使用App组件。

但是,您可以阅读this source ...

  

在ReactJS中,出现了“高阶组件”这一新兴概念。这些组件包含其他组件并提供其他行为和数据输入(通过属性)。

有时候将所有(或大部分)组件包装到单个最顶层组件中是有意义的,尤其是使其下面的组件是纯净的。也就是说,例如,它下面的组件将不会知道路由器或通量。他们将获得他们作为道具所需的一切。这有助于保持关注点的分离,但同样,您不需要这样做。

React router

react-router需要成为您的路线生效的最重要组成部分。因为react-router是根据当前URL确定要呈现哪个组件的那个。

Example taken from here

render((
  <Router>
    <Route path="/" component={App}>
      <Route path="about" component={About}/>
      <Route path="users" component={Users}>
        <Route path="/user/:userId" component={User}/>
      </Route>
    </Route>
  </Router>
), document.body)

终极版

我将Redux作为Flux实现的一个例子,因为它是最受欢迎的。对于Redux,包装应用程序是有意义的,因为它使用connect函数根据应用程序状态自动在应用程序上注入道具。它还会自动传递动作创建者。

Example taken from here

// App.js
// ... imports removed for simplicity
// Which part of the Redux global state does our component want to receive as props?
function mapStateToProps(state) {
  return {
    value: state.counter
  }
}

// Which action creators does it want to receive by props?
function mapDispatchToProps(dispatch) {
  return {
    onIncrement: () => dispatch(increment())
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App)

在上面的示例中,App将收到包含value应用状态的counter道具。它还将在onIncrement动作创建者处收到。尽管App组件是不可知的,但模块App.js知道Redux,但它下面的组件却不知道。

<强> TL; DR

你可以不使用高阶组件,但有时候它是有道理的。