你如何在 reactjs 应用程序中设置多个页面的 "body" 样式而不让它们相互重叠?

How would you style the "body" of multiple pages in a reactjs app without having them overlapping each other?

好的,伙计们。

在以各种不同的方式尝试了多种不同的方法之后,我来到这里是为了那些绝对知道这个简单问题的答案的专家。

所以,我遇到的问题是,每当我尝试将背景图像和其他属性添加到我正在创建的应用程序页面的“主体”时,它只会添加 CSS所有其他页面的单个页面。

如果这个问题听起来太沉重,让我归结为:

如何为多个页面的body标签添加不同的样式?

为了方便您,您可以看一下下面的代码:

这是登录文件

import React, { Fragment, useState } from 'react';

import { Link, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { login } from '../../../actions/auth';

import './Login.css';




const Login = ({ login, isAuthenticated }) => {

    const [formData, setFormData] = useState({
        email: '',
        password: ''
    })


    const { email, password } = formData;

    const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });

    const onSubmit = async e => {
        e.preventDefault();
        login(email, password)
    }

    if (isAuthenticated) {
        return <Redirect to="/dashboard" />
    }



    return (

        <Fragment>

            <section className="bodyLogin">
                <h1>Login</h1>
                <form className="loginForm" onSubmit={e => onSubmit(e)}>

                    <input type="email"
                        name="email"
                        placeholder="Email.............."
                        value={email}
                        onChange={e => onChange(e)}

                        required /> <br /><br />

                    <input type="password"
                        name="password"
                        placeholder="Password.............."
                        value={password}
                        onChange={e => onChange(e)}
                        required /><br /><br />

                    <div className="account-login">
                        <p>Don't have an account? <span><Link to="/register">Register</Link> </span></p>
                    </div>

                    <div className="btn-login">
                        <input type="submit" name="Login" defaultValue="Log In" />
                        <Link to="/"><input type="button" name="Back" defaultValue="Back" /> </Link>
                    </div>
                </form>
            </section>

        </Fragment>



    )



}


Login.propTypes = {

    login: PropTypes.func.isRequired,
    isAuthenticated: PropTypes.bool


}

const mapStateToProps = state => ({

    isAuthenticated: state.auth.isAuthenticated
});




export default connect(mapStateToProps, { login })(Login);

其css文件

html,
.Login>.bodyLogin {

    height: 100%;


}


.Login>.bodyLogin {


    background-image: url("/client/src/components/images/undraw_people_tax5.png"), url("/client/src/components/images/undraw_together_j0gj.png");

    background-size: 80% 100%, 101% 100%;
    background-repeat: no-repeat;
    background-position: 1% 60%, 80% 110%;





}

现在,我想为其他页面添加不同的背景图片。但是我得到了与 Login.js.

相同的图像

模块并没有真正起作用。你知道解决这个问题的方法吗?

我像这样添加以下功能组件:

const Login = ({ login, isAuthenticated }) => {


    useEffect(() => {
        document.querySelector('body').style.backgroundImage = url("../../images/undraw_people_tax5.png");
    })

但我被这个红色错误推到了!

在每个组件中添加以下语句

class 基于组件

componentDidMount() {
   document.querySelector('body').style.backgroundImage = 'url(/* image path */)';
}

功能组件

useEffect(() => {
   document.querySelector('body').style.backgroundImage = 'url(/* image path */)';
}, []);

使用不同的 class 名称,并通过不在全局样式中添加任何页面样式来将您的样式限制在您的页面中。我的意思是,为每个页面创建一个容器。并在该容器中保留所有页面元素和样式。我希望,它会有所帮助。

在 React 之外控制标记的推荐 React 实践是 React Helmet

在您的每个组件中,包含一个 Helmet 来定义正文样式(和其他属性),如下所示:


import Helmet from 'react-helmet';
function Page(props) {
    const bgColor = '#ddd';
    return (
       <div class="page">
                <Helmet>
                    {/* Define inline CSS for body tag */}
                    <body style="background-color: #ddd" />
                    {/* Or include in-file CSS */}
                    <style>
                       {`
                            body {
                                background-color: ${bgColor};
                            }
                       `}
                    </style>
                </Helmet>
                {/* Rest of your component content goes here ... /*}
       </div>
    );
}

Helmet 可以通过组件层次结构相互嵌套,功能类似于 CSS 级联,因此您可以自定义任何深度的 body (在 child 组件中) 随便你。

注意:此方法仅适用于在 React 外部的标记上定义 CSS,如 htmlbody。在 React 组件内部遵循更好的方法来导入受控 CSS,例如 CSS 模块 Styled Component

更新 1

在您的情况下,将 Helmet 放在 <Fragment> 的第一个 child 中:

     <Fragment>
         <Helmet>
             <style>
                {`
                   html, body {
                       height: 100%;
                  }

                 body {
                    background-image: url("/client/src/components/images/undraw_people_tax5.png"), url("/client/src/components/images/undraw_together_j0gj.png");
                    background-size: 80% 100%, 101% 100%;
                    background-repeat: no-repeat;
                    background-position: 1% 60%, 80% 110%;
                  }
                `}
            </style>
         </Helmet>
       {/* Rest of your Fragment goes here ... /*}
     </Fragment>

更新 2

如果您想使用 CSS 文件,而不是像这样内联所有内容,请将您的 import './Login.css) 替换为:

 const css = require('./Login.css').toString();

然后你的 <style> 可以只包含 CSS 字符串:

                <Helmet>
                    <style>
                        {css}
                    </style>
                </Helmet>