奇怪的 React 编译器行为

Posted

技术标签:

【中文标题】奇怪的 React 编译器行为【英文标题】:Strange React Compiler Behavior 【发布时间】:2019-05-22 20:23:00 【问题描述】:

我在ReactJS 上做这个项目。为来自bootstrap4 的元素放置reactstrap 模块。

我有reactstrap 标签:

import React, Component from 'react';
import 
    Button,
    Col,
    Container,
    Form,
    Input,
    InputGroup, InputGroupAddon, InputGroupText,
    Label,
    Nav,
    NavItem,
    NavLink,
    Row,
    TabContent,
    TabPane
 from "reactstrap";
import Link from "react-router-dom";
import classNames from 'classnames';
import Logo from "../../components/common/Logo";

import '../../style/page/auth/style.css';
import '../../style/page/auth/media.css';
import '../../style/page/auth/custom.css';

class LoginPage extends Component 

    constructor(props) 
        super(props);

        this.state = 
            activeTab: 'signInTab'
        ;

        this.toggle = this.toggle.bind(this);
        this.openTermsTab = this.openTermsTab.bind(this);
    

    componentDidMount() 
        document.title = "Авторизация";
    

    toggle(tab) 
        if (this.state.activeTab !== tab) 
            this.setState(
                activeTab: tab
            );
        
    

    openTermsTab(e) 
        e.preventDefault();
        this.toggle('termsTab');
    

    render() 
        return (
            <main className="align-middle">
                <Container>
                    <Row className="h-100 justify-content-center">
                        <Col xs="12" sm="12" md="8" lg="6" xl="6">
                            <div className="entry-box-wrapper">
                                <div className="entry-box modal-content">
                                    <div className="modal-body">

                                        <Nav pills justified>

                                            <NavItem>
                                                <NavLink
                                                    className=classNames( active: this.state.activeTab === 'signInTab' )
                                                    onClick=() =>  this.toggle('signInTab'); >
                                                    Авторизация
                                                </NavLink>
                                            </NavItem>

                                            <NavItem>
                                                <NavLink
                                                    className=classNames( active: this.state.activeTab === 'signUpTab' )
                                                    onClick=() => this.toggle('signUpTab')>
                                                    Регистрация
                                                </NavLink>
                                            </NavItem>

                                            <NavItem>
                                                <NavLink
                                                    className=classNames( active: this.state.activeTab === 'termsTab' )
                                                    onClick=this.openTermsTab>
                                                    Правила сервиса
                                                </NavLink>
                                            </NavItem>

                                        </Nav>

                                        <Logo className="d-block mx-auto mt-4" />

                                        <TabContent activeTab=this.state.activeTab>

                                            <TabPane tabId="signInTab">
                                                <hr/>
                                                <Form id="signInForm" >

                                                    <div className="form-group input-group">

                                                        <InputGroup>
                                                            <InputGroupAddon addonType="prepend">
                                                                <InputGroupText>
                                                                    <i className="fas fa-envelope"/>
                                                                </InputGroupText>
                                                            </InputGroupAddon>
                                                            <Input type="email" name="email" placeholder="Email" />
                                                        </InputGroup>

                                                    </div>

                                                    <div className="form-group input-group">

                                                        <InputGroup>
                                                            <InputGroupAddon addonType="prepend">
                                                                <InputGroupText>
                                                                    <i className="fas fa-unlock-alt"/>
                                                                </InputGroupText>
                                                            </InputGroupAddon>
                                                            <Input type="password" name="password" placeholder="Пароль" />
                                                        </InputGroup>

                                                    </div>

                                                    <Row>

                                                        <Col widths=["6"]>
                                                            <div className="custom-control custom-checkbox">
                                                                <Input
                                                                    type="checkbox"
                                                                    name="rememberMe"
                                                                    id="singInTabRememberMe"
                                                                    className="custom-control-input"/>
                                                                <Label
                                                                    for="singInTabRememberMe"
                                                                    className="custom-control-label">
                                                                    запомнить меня
                                                                </Label>
                                                            </div>
                                                        </Col>

                                                        <Col widths=["6"] className="text-center pl-0 pr-0">
                                                            <Link to="/admin/forgot" className="brand-link">
                                                                Не помню пароль
                                                            </Link>
                                                        </Col>

                                                    </Row>

                                                    <Button color="" className="float-right brand-nav-btn left-filling">
                                                        <i><img src=process.env.PUBLIC_URL + '/img/login2.png' /></i>
                                                        <span>
                                                            Вход
                                                        </span>
                                                    </Button>

                                                </Form>
                                            </TabPane>

                                            <TabPane tabId="signUpTab">
                                                <hr/>
                                                <Form>

                                                    <div className="form-group input-group">

                                                        <InputGroup>
                                                            <InputGroupAddon addonType="prepend">
                                                                <InputGroupText>
                                                                    <i className="fas fa-envelope"/>
                                                                </InputGroupText>
                                                            </InputGroupAddon>
                                                            <Input type="email" placeholder="Email" />
                                                        </InputGroup>

                                                    </div>

                                                    <div className="form-group input-group">

                                                        <InputGroup>
                                                            <InputGroupAddon addonType="prepend">
                                                                <InputGroupText>
                                                                    <i className="fas fa-unlock-alt"/>
                                                                </InputGroupText>
                                                            </InputGroupAddon>
                                                            <Input type="password" placeholder="Пароль" />
                                                        </InputGroup>

                                                    </div>

                                                    <div className="form-group input-group">

                                                        <InputGroup>
                                                            <InputGroupAddon addonType="prepend">
                                                                <InputGroupText>
                                                                    <i className="fas fa-unlock-alt"/>
                                                                </InputGroupText>
                                                            </InputGroupAddon>
                                                            <Input type="password" placeholder="Повторите пароль" />
                                                        </InputGroup>

                                                    </div>

                                                    <div className="custom-control custom-checkbox ">

                                                        <Input
                                                            type="checkbox"
                                                            name="example1"
                                                            id="chBxTermsArgee"
                                                            className="custom-control-input"/>

                                                        <Label
                                                            for="chBxTermsArgee"
                                                            className="custom-control-label">

                                                            согласен с

                                                            <a href="#" className="brand-link" id="serviceTermsLink"
                                                               onClick=this.openTermsTab>
                                                                 правилами сервиса
                                                            </a>

                                                        </Label>

                                                    </div>

                                                    <Button color="" className="float-right brand-nav-btn left-filling">
                                                        <i><img src=process.env.PUBLIC_URL + '/img/login2.png' /></i>
                                                        <span>
                                                            Отправить
                                                        </span>
                                                    </Button>

                                                </Form>

                                            </TabPane>

                                            <TabPane id="termsTab" tabId="termsTab">
                                                <hr/>
                                                <div className="service-terms">
                                                    <h3>Правила предоставления услуги</h3>
                                                    <p>
                                                        Lorem ipsum dolor sit amet consectetur adipisicing elit.
                                                        Ipsa, cumque
                                                        necessitatibus impedit delectus ratione harum nisi nemo
                                                        minus eaque,
                                                        exercitationem consequuntur. Repellat tempore molestias
                                                        dicta. Recusandae
                                                        quam rem ducimus temporibus!
                                                        Doloribus quibusdam ullam atque possimus sequi libero
                                                        inventore natus amet
                                                        facilis, minima dolore molestias accusantium nam omnis,
                                                        delectus totam fuga
                                                        quae nemo asperiores laboriosam veritatis! Ipsam aperiam
                                                        ipsa nulla vitae?
                                                        Temporibus nulla rem aspernatur eum quidem minima
                                                        voluptatum corporis libero
                                                        explicabo. Impedit distinctio deleniti labore
                                                        exercitationem quae
                                                        repudiandae consequatur? Ullam eveniet quo
                                                        exercitationem! Sint ab, nihil
                                                        placeat ea omnis libero!
                                                        Lorem ipsum, dolor sit amet consectetur adipisicing
                                                        elit. Cum, voluptatum
                                                        perspiciatis molestias reiciendis blanditiis pariatur in
                                                        sunt velit? Labore
                                                        assumenda repellendus sint molestiae debitis esse itaque
                                                        totam distinctio
                                                        perferendis reiciendis?
                                                    </p>
                                                </div>

                                            </TabPane>

                                        </TabContent>

                                    </div>

                                </div>

                            </div>

                        </Col>
                    </Row>
                </Container>
            </main>
        );
    


export default LoginPage;

更新!

所以它起作用了。 我想将选项卡的内容转移到单独的组件中,如下所示:

<TabContent activeTab=this.state.activeTab>
     <SignInTab/>
     <SignUpTab/>
     <TermsTab/>
</TabContent>

这里在编译的时候出错了:

./node_modules/reactstrap/src/Alert.js
SyntaxError: E:\IDEA\application\node_modules\reactstrap\src\Alert.js: Unexpected token (72:4)

  70 | 
  71 |   return (
> 72 |     <Fade ...attributes ...alertTransition tag=Tag className=classes in=isOpen role="alert" innerRef=innerRef>
     |     ^
  73 |       toggle ?
  74 |         <button type="button" className=closeClasses aria-label=closeAriaLabel onClick=toggle>
  75 |           <span aria-hidden="true">&times;</span>

为什么?

package.json


  "name": "front-end-react-v1",
  "version": "0.1.0",
  "private": true,
  "dependencies": 
    "ajv": "^6.6.2",
    "ajv-keywords": "^3.2.0",
    "classnames": "^2.2.3",
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-native": "^0.57.8",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1",
    "react-router-native": "^4.3.0",
    "react-scripts": "^2.1.1",
    "reactstrap": "^6.5.0"
  ,
  "scripts": 
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  ,
  "eslintConfig": 
    "extends": "react-app"
  ,
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": 
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.4",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1"
  

【问题讨论】:

您如何在开发和生产中运行?它们是相同的命令吗? 我在 IntlijIDEA 中使用命令 npm start 运行。 你能创建 stackblitz 来重现这个问题吗? 将文件重命名为Alert.jsx 有帮助吗? Alert 未在您发布的代码中的任何地方使用。考虑提供可以复制问题的***.com/help/mcve。您收到此错误意味着您在某处导入了reactstrap/src(这不应该这样做),或者您错误地配置了 Webpack。后者可以排除,因为您没有弹出 CRA 项目。 【参考方案1】:

错误出现在./node_modules/reactstrap/src/Alert.js意味着组件是从reactstrap/src/...而不是reactstrap导入的(后者指向reactstrap/dist/...)。

reactstrap/src 导入的问题在于它包含需要转译的代码。它不应该在没有充分理由的情况下导入,因为项目通常配置为不从node_modules 转换模块,这会导致开销和潜在问题。在create-react-app 生成的应用程序中,如果不修改 Webpack 配置,则无法更改。

IDE 自动导入通常会添加不正确的导入,例如 reactstrap/src/...

万一有

import Alert from 'reactstrap/src/Alert.js';

import,应该改成

import  Alert  from 'reactstrap';

【讨论】:

以上是关于奇怪的 React 编译器行为的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的编译器行为 (C++)

奇怪的编译器行为 - 可选参数

gcc 4.6 编译器的奇怪行为

关于 C++ 中默认构造函数的奇怪编译器行为

Visual Studio C++ 编译器在局部变量对象上的奇怪行为

Windows 共享内存和不同的编译器奇怪的行为