我正在使用react进行项目,我有一个注册模式和一个登录模式,它们都是独立的组件,我希望有两个链接吃掉每个模态的顶部,以便能够从注册切换模型到登录模型。每个组件模型都有一个打开的函数,如下所示:
open() {
this.setState({ showModal: true });
}
组件是否有办法调用函数并从另一个组件设置状态,或者我是否需要以某种方式将两个模型设为一个组件?
答案 0 :(得分:4)
处理组件之间通信的最佳方法是通过所有组件“挂钩”的应用程序的状态容器。
这是一个非常简单的插图:
// 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
时,它会更改状态中的相应标志,映射到组件上的showModal*
道具。然后组件重新渲染并包含适当的模态。如果要从另一个组件触发模态,可以在应用程序状态和更改中更改相应的标志。 React将重新渲染并显示模态。
上面的例子非常不完整 - 它只是为了说明基本的想法。要使其工作,您需要为应用程序实现状态容器。为此,我建议使用flux pattern或redux。
现在,您可以将其实现为一组回调&amp;特定于您正在使用的组件的属性,但我建议不要这样做 - 它很难非常,很快非常。此外,它无法扩展 - 要添加组件,您必须手动将其“连接”到所有其他组件。
答案 1 :(得分:3)
在渲染每个登录模式的组件中,您希望通过每个组件的props传递值。在模态组件中,您将使用传入的属性的值来确定是否应该显示模态。
以下是它如何运作的一个简单例子(理论上 - 未经过测试):
登录/注册模式
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} />
);
},
});