【问题标题】:Why css styles leaks (gets inherited by other components) out of the component when they use the same class names in react.js?为什么 css 样式在 react.js 中使用相同的类名时会从组件中泄漏(被其他组件继承)?
【发布时间】:2021-03-15 22:28:23
【问题描述】:

我在“创建反应应用程序”中创建了两个单独的组件。对于每个组件,我都有一个专用的样式表。如果我在两个组件中使用相同的类名,那么样式也会被继承到另一个组件。

在这里,即使我将 Quote.scss 文件保留为空,样式也会从 Contact 组件的 contact.css 文件继承。

在这里,您可以看到我没有在 Quote.jsx 文件中导入 Contact.css 样式表。

有什么办法可以避免这种情况,同时仍然在不同的组件中使用相同的类名?

我在项目中的文件夹结构-

ContactPage
  Contact.jsx
  Contact.scss
  Contact.css
QuotePage
  Quote.jsx
  Quote.scss
  Quote.css

Contact.jsx 文件-

import "./Contact.css";
import React, {useState} from 'react';
import axios from "axios";

      <div className="form">
            <div className='container'>
                <div className="input-row">
                    <div className="block">
                        <label>First Name</label>
                        <input className="input" type="text" name="fName" onChange={handleChange} value={postData.fName} />
                    </div>  
                    <div className="block">
                        <label >Last Name</label>
                        <input className="input" type="text" name="lName" onChange={handleChange} value={postData.lName}/>
                    </div>  
                </div>

                <div className="input-row">
                    <div className="block">
                        <label>Email</label>
                        <input className="input is-success" type="email" name="email" onChange={handleChange} value={postData.email}/>
                    </div>
                    <div className="block">
                        <label >Phone</label>
                        <input className="input" type="tel" name="phone" onChange={handleChange} value={postData.phone}/>
                    </div>  
                </div>

                <div className="textarea-row">
                    <div className="block">
                        <label >Message</label>
                        <textarea className="textarea" name="message" onChange={handleChange} value={postData.message}></textarea>
                    </div>
                </div>
                    {/* row-3 */}
                <div className="btn-row">
                    <button className="submit-btn" onClick={handleSubmit}>Submit</button>
                    <button className="cancel-btn" onClick={handleCancel}>Cancel</button>
                </div>
                <div className='submit-message'>
                    <h1>{message}</h1>
                </div>
            </div>
        </div>

我的 Contact.scss 文件-

@mixin section {
    padding: 4rem 0;
    height: auto;
}

@mixin container {
    width: auto;
    height: auto;
    max-width:1100px;
    padding: 0 40px;
    margin: 0 auto;
    align-items:center;
    @media screen and (max-width:768px){
        grid-template-columns: 1fr;
        grid-gap: 1rem;
        width: auto;
        height: auto;
        max-width:none;
        padding: 0 40px;
        margin: 0 auto;
        align-items:none;
    }
}

label{
    font-weight: 400;
}

.form{
    @include section;
    .container{
        @include container;
        display: grid;
        grid-template-rows: auto auto auto auto;
        grid-row-gap: 2rem;
        .input-row{
            display: grid;
            grid-template-columns: 1fr 1fr;
            grid-gap: 1rem;
            input{
                padding-left: 1rem;
                height: 2.5rem;
                outline: coral solid 1px;
                border: none;
                font-size: 1.2rem;
                font-weight: 100;
                &:focus {
                    outline: #0b5a68 solid 1px;
                    border: none;
                    box-shadow: 0 0 4px #0b5a68;
                }
            }
            @media screen and (max-width:768px){
                grid-template-columns: 1fr;
                align-self: center;
                justify-content: center;
            }
            .block{
                display: grid;
                grid-template-rows: auto auto;
                grid-gap:.25rem;
            }
        }
        .textarea-row{
            @media screen and (max-width:768px){
                grid-template-columns: auto;
                align-self: center;
                justify-content: center;
            }
            .block{
                display: grid;
                grid-template-rows: auto auto;
                grid-gap:.25rem;
                @media screen and (max-width:768px){
                    grid-template-columns: 1fr;
                    align-self: center;
                    justify-content: center;
                }
                textarea{
                    padding-left: 1rem;
                    height: 2.5rem;
                    outline: coral solid 1px;
                    border: none;
                    &:focus {
                        outline: #0b5a68 solid 1px;
                        box-shadow: 1px 1px 20px #0b5a68;
                        border: none;
                        box-shadow: 0 0 4px #0b5a68;
                    }
                    height: 4rem;
                    padding: 1rem 0 0 1rem;
                    font-size: 1.2rem;
                    font-weight: 100;
                }
            }
        }
        .btn-row{
            display: grid;
            grid-template-columns: 1fr 1fr 1fr 1fr;
            grid-gap:1rem;
            @media screen and (max-width:768px){
                grid-template-columns: auto;
                align-self: center;
                justify-content: center;
                grid-template-columns: 1fr 1fr;
            }
            .submit-btn{
                display: grid;
                justify-content: center;
                align-items: center;
                width: 100%;
                color: white;
                background-color: #108397;
                border: solid #108397 2px;
                border-radius: 4px;
                padding: 1rem 1rem;
                text-decoration: none;
                font-size: 1rem;
                font-weight: 600;
                outline: none;
                &:hover{
                    background-color: #0b5a68;
                    border: solid #0b5a68 2px;
                    transition: ease .3s;
                }
            }
            .cancel-btn{
                display: grid;
                justify-content: center;
                align-items: center;
                width: 100%;
                color: white;
                background-color: #df60b5c7;
                border: solid #df60b59c 2px;
                border-radius: 4px;
                padding: 1rem 1rem;
                text-decoration: none;
                font-size: 1rem;
                font-weight: 600;
                outline: none;
                &:hover{
                    background-color: #b4348a;
                    border: solid #b4348a 2px;
                    transition: ease .3s;
                }
            }
        }
    }
}

我的 Quote.jsx 文件-

import './Quote.css';
import React, { useState } from 'react';
import axios from 'axios';

<div className="form">
    <div className='container'>
        <fieldset className='preference'>
            <legend>Select your preference</legend>
            <div className="preference-row">
                <input className="check" checked={radio==="short-term-use"} onChange={e=>setRadio(e.target.value)} type="radio" name="shortTermUse" value="short-term-use" />
                <label for="short-term-use">Short Term Use</label>
            </div>
            <div className="preference-row">
                <input className="check" checked={radio==="long-term-use"} onChange={e=>setRadio(e.target.value)} type="radio"  name="longTermUse" value="long-term-use" />
                <label for="long-term-use">Long Term Use</label>
            </div>  
        </fieldset>
        <div className="btn-row">
                <button className="submit-btn" onClick={handleSubmit}>Submit</button>
                <button className="cancel-btn" onClick={handleCancel}>Cancel</button>       
        </div>
    </div>
</div>

我的 Quote.scss 文件-

// it's empty

【问题讨论】:

    标签: css reactjs sass frontend scss-mixins


    【解决方案1】:

    React 默认没有类封装,如果你想实现 CSS 样式封装,可以阅读this article 了解你的选项

    另请参阅@Jacob Smit 在下面的评论中提到的CSS modules

    【讨论】:

    • 虽然这经历了很多可用的选项,但它没有提到 CSS 模块。如果这个问题是从 Angular 到 React 的结果,我觉得 CSS 模块是最接近 Angular 提供的体验。如果正在使用 CRA (create-react-app),那么它有设置 CSS Modules 的说明
    • @Jacob Smit 你说得对,我提到的文章不是我的,只是作为参考提到的,我仍然记得我在主要使用 angular 后开始使用 react 时发现它没有的沮丧'不封装样式,但是我现在已经可以接受了。
    • 感谢@ShmiliBreuer 和 Jacob Smit 提出的宝贵建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 2017-05-09
    • 2021-02-19
    • 2018-09-06
    • 2018-12-03
    • 2015-06-01
    相关资源
    最近更新 更多