React:如何从另一个组件访问一个组件?

React: How do I access a component from another component?

我正在使用 React 开发一个项目,我有一个注册模式和一个登录模式,它们都是独立的组件,我希望每个模式的顶部都有两个链接,以便能够从注册模型到登录模型。每个组件模型都有一个打开的函数,如下所示:

  open() {
    this.setState({ showModal: true });
  }

有没有办法让一个组件调用一个函数并从另一个组件设置状态,或者我是否需要以某种方式使两个模型成为一个组件?

处理组件间通信的最佳方式是通过应用程序的状态容器,所有组件 "hook in to"。

这是一个非常的简单插图:

// this state is defined somewhere in your application
// all of your components "hook in to" this state by including
// the values you want as props. For example,
//     <MyFancyComponent value={state.value1} />
// and now MyFancyComponent has access to value1
state = {
    value1: 42,
    showModal1: false,
    showModal2: false,
};


// somewhere in your application, there's a render method
// that looks like this
render() {
    return (
        <div>

            {this.props.showModal1 ? <Modal1 /> : null}
            {this.props.showModal2 ? <Modal2 /> : null}

            {/* now render the rest of your component */}

        </div>
    );
}

基本思路是,当这个组件(上面有render方法的那个)需要显示Modal1或者Modal2的时候,它改变状态中相应的flag,映射到组件上的 showModal* 道具。然后组件重新呈现并包含适当的模态。如果您想从另一个组件触发模态,您可以更改应用程序状态中的相应标志,React 将开始重新渲染并显示模态。

上面的示例非常不完整 - 它只是为了说明基本思想。为了使这项工作正常进行,您需要为您的应用程序实现一个状态容器。为此,我建议 flux pattern or redux.

现在,您可以将此实现为一组特定于您正在使用的组件的回调和属性,但我不建议这样做 - 它变成 非常难以管理,非常很快。此外,它无法缩放 - 要添加一个组件,您必须手动 "wire it up" 到所有其他组件。

在呈现每个登录模式的组件中,您可能希望通过每个组件的道具传递值。在模态组件中,您将使用传入的 属性 的值来确定是否应显示模态。

这是一个简单的例子,说明它是如何工作的(理论上——还没有测试):

Login/Signup 模态

import React from 'react';

const LoginModal = React.createClass({
  propTypes: {
    isVisible: React.PropTypes.boolean.isRequired,
    onLogin: React.PropTypes.function,
  },

  componentWillReceiveProps(nextProps) {
    // Will allow parent components to pass in a boolean
    // telling this component when to render
    this.setState({
      showModal: nextProps.isVisible,
    });
  },

  onSubmit() {
    // TODO: Handle login

    // If we let the parent handle the visibility, we just call
    // the onLogin callback passed in and don't set this.state.showModal
    this.props.onLogin();
  },

  render() {
    return (
      // Use this.state.showModal boolean to show/hide
      // your login modal
    );
  },
});

export default LoginModal;

父组件

import React from 'react';
import LoginModal from './LoginModal';

const ParentComponent = React.createClass({
  showLoginModal() {
    this.setState({
      showLogin: true,
    });
  },

  hideLoginModal() {
    this.setState({
      showLogin: false,
    });

    // TODO: Likely change the route or do something else here...
  },

  render() {
    return (
      <button onClick={this.showLoginModal}>Login</button>

      <LoginModal isVisible={this.state.showLogin} onLogin={this.hideLoginModal} />
    );
  },
});