这是我的Navigation
组件
import React from 'react';
import {Navbar, Nav, NavItem, Modal, Button, FormControl} from 'react-bootstrap';
import {BrowserRouter, Link, Route, Switch} from 'react-router-dom';
import Questions from './Questions';
import {About} from './About';
import {Home} from './Home';
import {LinkContainer} from 'react-router-bootstrap';
import Question from './Question';
import firebase from '../firebase';
class Navigation extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.openLogin = this.openLogin.bind(this);
this.handleClose = this.handleClose.bind(this);
}
componentDidMount() {
firebase.auth().onAuthStateChanged(user => {
if (user) {
console.log(user);
this.setState(
{
user: user
}, () => this.props.checkUserState(this.state.user)
);
}
});
}
logout() {
firebase.auth().signOut()
.then(() => {
this.setState({
user: null
}, function () {
this.props.checkUserState(this.state.user)
});
});
}
login() {
var email = document.getElementById('email').value;
var password = document.getElementById('password').value;
firebase.auth().signInWithEmailAndPassword(email, password)
.then(result => {
const user = result.user;
this.setState({
user: user,
},
function () {
this.props.checkUserState(this.state.user)
});
document.getElementById('close').click();
document.getElementById('questions').click();
}
).catch(e => console.log(e));
}
openLogin() {
this.setState({show: true});
}
handleClose() {
this.setState({show: false});
}
render() {
return (
<React.Fragment>
<BrowserRouter>
<React.Fragment>
<Navbar>
<Navbar.Header>
<Navbar.Brand>
<Link id='home' to="/">UczIchApp</Link>
</Navbar.Brand>
</Navbar.Header>
<Nav>
<LinkContainer id='about' to='/about'>
<NavItem>O nas</NavItem>
</LinkContainer>
{
this.state.user ?
<React.Fragment>
<LinkContainer id="questions" to='/questions'>
<NavItem>Zadania</NavItem>
</LinkContainer>
<NavItem onClick={this.logout}>Wyloguj się</NavItem>
</React.Fragment>
:
<NavItem onClick={this.openLogin}>Zaloguj się</NavItem>
}
</Nav>
</Navbar>
<Switch>
<Route exact path="/about" component={About}/>
<Route exact path="/questions" component={Questions}/>
<Route exact path="/" component={Home}/>
<Route path='/question/:id' component={Question}/>
</Switch>
</React.Fragment>
</BrowserRouter>
<Modal
show={this.state.show}
onHide={this.handleClose}>
<Modal.Header
closeButton>
<Modal.Title> Modal
heading </Modal.Title>
</Modal.Header>
<Modal.Body>
<form>
<FormControl
id="email"
type="email"
label="Email address"
placeholder="Enter email"/>
<FormControl id="password" label="Password" type="password"/>
<Button onClick={this.login}>Zaloguj</Button>
</form>
</Modal.Body>
<Modal.Footer>
<Button id="close" onClick={this.handleClose}>Close</Button>
</Modal.Footer>
</Modal>
</React.Fragment>
)
}
}
export default Navigation;
正如您所看到的,这个Navigation
组件正在做太多事情。我想把它分开,但是当我尝试时,我意识到它有很多联系。
例如,我尝试将Modal
带到一个单独的组件,但是我需要将所有登录逻辑移入其中,所以我认为它有点无意义,因为使用user
组件中的Navigation
我需要将整个代码移动到新文件中,从而重新创建问题。
我知道这是编写代码的错误方法,而我 不 要求为我重写它,但是如果有人经历过它给我一些关于如何划分它的技巧,我可以自己做。
我在想:将Modal
移到另一个组件,并将所有登录和注销逻辑移动到另一个组件。问题是我把它全部链接在一个文件中。我现在该如何解决它?
通过链接,我的意思是我在这里使用一个状态对象。
答案 0 :(得分:2)
您将在许多反应项目中看到的常见模式是将容器组件与Presenter组件分开。在您的情况下,删除一些Presenter组件以破坏您的应用程序将非常容易。
如果您还没有这样做,请阅读文档,尤其是Lifting State Up和Thinking in React。它很好地解释了这些概念。
答案 1 :(得分:1)
你可以将模态拆分成一个单独的组件,并将其所需的信息作为道具传递给你。 this.login
,this.handleClose
和this.state.show
。如:
<ModalComponent show={this.state.show} close={this.handleClose} login={this.login} />
然后,可以将导航组件中执行登录的逻辑移动到服务,并且如果需要,可以将服务方法作为道具传递而不是生活在导航组件上。
您可以修改login
方法,将用户名和密码作为参数。然后在按钮上单击以登录传递这些值。