简体   繁体   English

划分React.js组件

[英]Dividing React.js component

This is my Navigation component 这是我的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;

As you can see, this Navigation component is doing way too many things. 如您所见,此Navigation组件执行了太多操作。 I want to divide it up, but when I try, I realize there is a lot of linkage in it. 我想将其分解,但是当我尝试时,我意识到其中有很多联系。

For example I tried taking the Modal to a separate component, but then I'd need to move all login logic into it, so I figured it's kind of pointless, since to use the user in the Navigation component I'd need to just move the whole code to the new file, thus just recreating the issue. 例如,我尝试将Modal带到一个单独的组件中,但是随后我需要将所有登录逻辑移入其中,因此我认为它毫无意义,因为要在Navigation组件中使用user ,我只需要移动将整个代码保存到新文件中,从而重新创建问题。

I know this is a wrong way of writing code, and I'm not asking to rewrite it for me, but if someone who went through it could give me a couple of tips on how to divide it, I could do it myself. 我知道这是编写代码的错误方式,我不是要为我重写代码,但是如果经历过它的人可以给我一些如何划分代码的提示,我可以自己做。

What I was thinking: Move Modal to a different component and move all login and logout logic to a different component. 我在想什么:将Modal移至其他组件,并将所有登录和注销逻辑移至其他组件。 The problem is I linked it all in one file. 问题是我将所有链接链接到一个文件中。 How can I get around it now? 我现在该如何解决?

By linkage I mean I'm using one state object for everything here. 通过链接,我的意思是我将一个状态对象用于此处的所有内容。

A common pattern you will see in many react projects is to separate Container Components from Presenter Components. 在许多React项目中,您会看到一个常见的模式是将Container组件与Presenter组件分开。 In your case, it would be fairly easy to strip out some Presenter Components to break you app up. 在您的情况下,剥离一些Presenter组件来破坏您的应用相当容易。

Read the docs, especially Lifting State Up and Thinking in React if you have not already done so. 阅读文档,尤其是如果尚未阅读文档,尤其是在React中 提升状态思考 It explains theses concepts really well. 它很好地解释了这些概念。

You could split modal out into a separate component and pass the information it requires in through as props eg. 您可以将模式分解为一个单独的组件,并将所需信息传递为道具。 this.login , this.handleClose and this.state.show . this.loginthis.handleClosethis.state.show Such as: 如:

<ModalComponent show={this.state.show} close={this.handleClose} login={this.login} />

Then the logic to perform the login in the navigation component could be moved to a service and the service methods could be passed in as props instead of them living on the Navigation component if this is needed. 然后,可以将在导航组件中执行登录的逻辑移至服务,并且可以根据需要将服务方法作为道具传递,而不是将其驻留在导航组件中。

You could modify the login method to take the username and password as parameters. 您可以修改login方法,以用户名和密码作为参数。 And then on the button click to login pass those values in. 然后在按钮上单击登录以传递这些值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM