react 组件样式_如何设置React组件的样式

本文介绍了如何使用React组件样式化的三种方法:纯CSS,样式对象和JSS库。通过创建一个可显示成功或错误样式的组件示例,探讨了每种方法的优缺点,包括样式冲突的处理和组件重用性。通过实例展示了如何导入CSS,创建内联样式对象以及使用JSS动态创建CSS类名,确保样式唯一性。文章还强调了JSS提供的动态属性和主题化的可能性。
摘要由CSDN通过智能技术生成

react 组件样式

The author selected Creative Commons to receive a donation as part of the Write for DOnations program.

作者选择了创用CC来接受捐赠,这是Write for DOnations计划的一部分。

介绍 (Introduction)

In this tutorial, you’ll learn three different ways to style React components: plain Cascading Style Sheets (CSS), inline styles with JavaScript-style objects, and JSS, a library for creating CSS with JavaScript. These options each have advantages and disadvantages, some giving you more protection against style conflicts or allowing you to directly refer to props or other dynamic data. But all the options have one thing in common: They let you keep your component-specific styles close to the component, making components easier to reuse across a project or even across many unrelated projects.

在本教程中,您将学习三种不同的方式来对React组件进行样式设置:普通级联样式表(CSS) ,具有JavaScript样式对象的内联样式以及JSS (用于使用JavaScript创建CSS的库)。 这些选项各有优缺点,有一些可以使您免受样式冲突的影响,或者可以直接引用道具或其他动态数据。 但是所有选项都有一个共同点:它们使您可以将特定于组件的样式保持在组件附近,从而使组件更容易在项目中甚至在许多不相关的项目中重复使用。

Each of these options relies on CSS properties. To use plain CSS without any runtime data, you can import style sheets. If you want to create styles that are integrated with the component, you can use inline style objects that use CSS property names as keys and the style as the value. Finally, if you want a combination, you can use a third-party library such as JSS to write your CSS in JavaScript syntax, a software concept known as CSS-in-JS.

这些选项均依赖于CSS属性。 要使用不带任何运行时数据的纯CSS,可以导入样式表。 如果要创建与组件集成的样式,则可以使用将CSS属性名称用作键并将样式用作值的内联样式对象。 最后,如果需要组合,则可以使用第三方库(例如JSS)以JavaScript语法(一种称为CSS-in-JS的软件概念)编写CSS。

To illustrate these methods, you’ll build an example alert component that will either show a success style or an error style depending on the prop. The alert component will take any number of children. This means you will need to be cautious about style conflicts, since you have no way of knowing what styles the children components will have. After making the alert component, you will refactor it using each of the styling options so that you can see the similarities and differences between the approaches.

为了说明这些方法,您将构建示例alert组件,该组件将根据prop显示成功样式或错误样式。 alert组件将容纳任意数量的子代。 这意味着您将需要谨慎对待样式冲突,因为您无法知道子组件将具有哪些样式。 制作alert组件后,您将使用每个样式选项对其进行重构,以便可以看到方法之间的异同。

先决条件 (Prerequisites)

第1步-创建一个空项目 (Step 1 — Creating an Empty Project)

In this step, you’ll create a new project using Create React App. Then you will delete the sample project and related files that are installed when you bootstrap the project. Finally, you will create a simple file structure to organize your components. This will give you a solid basis on which to build this tutorial’s sample application for styling in the next step.

在这一步中,您将使用Create React App创建一个新项目。 然后,您将删除示例项目以及在引导项目时安装的相关文件。 最后,您将创建一个简单的文件结构来组织您的组件。 这将为您提供坚实的基础,以便在下一步中构建本教程的示例应用程序以进行样式设置。

To start, make a new project. In your terminal, run the following script to install a fresh project using create-react-app:

首先,创建一个新项目。 在您的终端中,运行以下脚本以使用create-react-app安装新项目:

  • npx create-react-app styling-tutorial

    npx create-react-app 样式指南

After the project is finished, change into the directory:

项目完成后,转到目录:

  • cd styling-tutorial

    cd 样式教程

In a new terminal tab or window, start the project using the Create React App start script. The browser will auto-refresh on changes, so leave this script running while you work:

在新的终端标签或窗口中,使用Create React App启动脚本启动项目。 浏览器将自动刷新所做的更改,因此在工作时请保持此脚本运行:

  • npm start

    npm开始

You will get a running local server. If the project did not open in a browser window, you can open it with http://localhost:3000/. If you are running this from a remote server, the address will be http://your_domain:3000.

您将获得正在运行的本地服务器。 如果未在浏览器窗口中打开项目,则可以使用http://localhost:3000/打开它。 如果您是从远程服务器运行的,则该地址将为http:// your_domain :3000

Your browser will load with a simple React application included as part of Create React App:

您的浏览器将加载一个简单的React应用程序,该应用程序是Create React App的一部分:

You will be building a completely new set of custom components, so you’ll need to start by clearing out some boilerplate code so that you can have an empty project.

您将构建一套全新的自定义组件,因此您需要从清除一些样板代码开始,以便拥有一个空项目。

To start, open src/App.js in a text editor. This is the root component that is injected into the page. All components will start from here. You can find more information about App.js at How To Set Up a React Project with Create React App.

首先,在文本编辑器中打开src/App.js 这是注入页面的根组件。 所有组件将从此处开始。 您可以在如何使用创建React App设置React项目中找到有关App.js更多信息。

Open src/App.js with the following command:

使用以下命令打开src/App.js

  • nano src/App.js

    纳米src / App.js

You will see a file like this:

您将看到如下文件:

styling-tutorial/src/App.js
styling-tutorial / src / App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

Delete the line import logo from './logo.svg';. Then replace everything in the return statement to return a set of empty tags: <></>. This will give you a valid page that returns nothing. The final code will look like this:

import logo from './logo.svg';删除行import logo from './logo.svg'; 。 然后替换return语句中的所有内容以返回一组空标签: <></> 。 这将为您提供一个不返回任何内容的有效页面。 最终代码如下所示:

styling-tutorial/src/App.js
styling-tutorial / src / App.js
import React from 'react';
import './App.css';

function App() {
  return <></>;
}

export default App;

Save and exit the text editor.

保存并退出文本编辑器。

Finally, delete the logo. You won’t be using it in your application and you should remove unused files as you work. It will save you from confusion in the long run.

最后,删除徽标。 您将不会在应用程序中使用它,并且应在工作时删除未使用的文件。 从长远来看,它将使您避免混乱。

In the terminal window type the following command:

在终端窗口中,输入以下命令:

  • rm src/logo.svg

    rm src / logo.svg

If you look at your browser, you will see a blank screen.

如果您查看浏览器,将会看到一个空白屏幕。

Now that you have cleared out the sample Create React App project, create a simple file structure. This will help you keep your components isolated and independent.

现在,您已经清除了示例创建React App项目,创建一个简单的文件结构。 这将帮助您使组件保持隔离和独立。

Create a directory called components in the src directory. This will hold all of your custom components.

src目录中创建一个名为components的目录。 这将保存您所有的自定义组件。

  • mkdir src/components

    mkdir src /组件

Each component will have its own directory to store the component file along with the styles, images, and tests.

每个组件都有自己的目录来存储组件文件以及样式,图像和测试。

Create a directory for App:

App创建目录:

  • mkdir src/components/App

    mkdir src / components / App

Move all of the App files into that directory. Use the wildcard, *, to select any files that start with App. regardless of file extension. Then use the mv command to put them into the new directory:

将所有App文件移到该目录。 使用通配符*来选择以App.开头的任何文件App. 无论文件扩展名如何。 然后使用mv命令将它们放入新目录:

  • mv src/App.* src/components/App

    mv src / App。* src / components / App

Next, update the relative import path in index.js, which is the root component that bootstraps the whole process:

接下来,更新index.js的相对导入路径,它是引导整个过程的根组件:

  • nano src/index.js

    纳米src / index.js

The import statement needs to point to the App.js file in the App directory, so make the following highlighted change:

import语句需要指向App目录中的App.js文件,因此请进行以下突出显示的更改:

styling-tutorial/src/index.js
样式教程/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Save and exit the file.

保存并退出文件。

Now that the project is set up, you can create your first component.

现在已经建立了项目,您可以创建第一个组件。

第2步-使用纯CSS样式化组件 (Step 2 — Styling a Component with Plain CSS)

In this step, you’ll build a sample Alert component that will display an alert on a web page. You’ll style this using plain CSS, which you will import directly into the component. This will ensure that the component’s styles remain closely coupled with the component’s JavaScript and JSX. You’ll also create a component that will implement the Alert component to see how styles can affect children and how you can use props to change styles dynamically.

在此步骤中,您将构建一个示例Alert组件,该组件将在网页上显示警报。 您将使用纯CSS设置样式,将其直接导入组件中。 这将确保组件的样式与组件JavaScript和JSX保持紧密结合。 您还将创建一个组件,该组件将实现Alert组件,以查看样式如何影响子对象以及如何使用props动态更改样式。

By the end of this step, you’ll have created several components that use plain CSS imported directly into the component.

在此步骤结束时,您将创建几个使用直接导入到组件中的纯CSS的组件。

构建警报组件 (Building an Alert Component)

To start, create a new Alert component. First, make the directory:

首先,创建一个新的Alert组件。 首先,建立目录:

  • mkdir src/components/Alert

    mkdir src / components / Alert

Next, open Alert.js:

接下来,打开Alert.js

  • nano src/components/Alert/Alert.js

    纳米src / components / Alert / Alert.js

Add a basic component that returns the string Alert:

添加一个返回字符串Alert的基本组件:

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';

export default function Alert() {
  return <div>Alert</div>
}

Save and close the file.

保存并关闭文件。

Next, open App.js:

接下来,打开App.js

  • nano src/components/App/App.js

    纳米src / components / App / App.js

Import the Alert component and render it inside a <div> by adding the highlighted code:

通过添加突出显示的代码,导入Alert组件并将其呈现在<div>

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';
import './App.css';

import Alert from '../Alert/Alert';

function App() {
  return (
    <div className="wrapper">
      <Alert />
    </div>
  )
}

export default App;

In this code, you gave the <div> a className of wrapper, which will be used for styling later.

在此代码中,您为<div>提供了wrapperclassName ,该名称将在以后用于样式设置。

Save and close the file. When you do, the browser will refresh and you’ll see your component:

保存并关闭文件。 完成后,浏览器将刷新,您将看到您的组件:

Next, you will style the App component to give it some padding so that the Alert component is not so close to the edge. Open the App.css file:

接下来,您将对App组件进行样式设置以为其添加一些填充,以使Alert组件离边缘不那么近。 打开App.css文件:

  • nano src/components/App/App.css

    纳米src / components / App / App.css

This file uses standard CSS. To add padding to the wrapper, replace the default code with a rule as you would for CSS in a plain HTML project. In this case, add a padding of 20px:

该文件使用标准CSS。 要将填充添加到包装中,请使用规则替换默认代码,就像在纯HTML项目中使用CSS替换规则一样。 在这种情况下,请添加20pxpadding

styling-tutorial/src/components/App/App.css
样式教程/src/components/App/App.css
.wrapper {
    padding: 20px;
}

Save and close the file. When you do, the page will refresh and you’ll see the extra padding:

保存并关闭文件。 完成后,页面将刷新,您将看到额外的填充:

When you use Create React App, webpack will take the imported CSS and add it to a style tag at the top of the file rendered in the browser. If you look at the <head> element in your page source, you’ll see the styles:

当您使用Create React App时, webpack将采用导入CSS,并将其添加到浏览器中呈现的文件顶部的样式标签中。 如果查看页面源文件中的<head>元素,则会看到以下样式:

This means that you can keep the CSS alongside the component and it will be collected together during the build phase. It also means that your styles are global in scope, which can create potential name conflicts. With this method, each class name will need to be unique across all components.

这意味着您可以将CSS保留在组件旁边,并在构建阶段将其收集在一起。 这也意味着您的样式在全局范围内,可能会造成潜在的名称冲突。 使用此方法,每个类名在所有组件中都必须是唯一的。

To explore this problem, you will make some changes to the Alert component.

要研究此问题,您将对“ Alert组件进行一些更改。

First, open the file:

首先,打开文件:

  • nano src/components/Alert/Alert.js

    纳米src / components / Alert / Alert.js

Then add some React code that will take children, type, and title as props:

然后添加一些代码做出React,将采取childrentype ,以及title为道具:

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';
import PropTypes from 'prop-types';

export default function Alert({ children, title, type }) {
  return (
    <div>
      <h2>{title}</h2>
      {children}
    </div>
  )
}

Alert.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.element), 
    PropTypes.element.isRequired
  ]),
  title: PropTypes.string.isRequired,
  type: PropTypes.string.isRequired,
}

The title in this code is in a <h2> tag, and children will allow you to display child components. You will soon use the type prop to set a success and an error alert based on the PropTypes typing system.

此代码中的title位于<h2>标记中,并且children将允许您显示子级组件。 您将很快使用prop type根据PropTypes类型系统设置成功和错误警报。

Save and close the file. Next, update the Alert component in App to use the new props.

保存并关闭文件。 接下来,更新AppAlert组件以使用新道具。

First, open App.js:

首先,打开App.js

  • nano src/components/App/App.js

    纳米src / components / App / App.js

Make an alert that notifies a user that an attempt to add items to a shopping cart has failed:

发出警报,通知用户尝试将商品添加到购物车失败:

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';
import './App.css';

import Alert from '../Alert/Alert';

function App() {
  return (
    <div className="wrapper">
      <Alert title="Items Not Added" type="error">
        <div>Your items are out of stock.</div>
      </Alert>
    </div>
  )
}

export default App;

In this code, you updated the title and children with a fail message, then added a type of error.

在此代码中,您使用失败消息更新了titlechildren ,然后添加了error type

Save and close the file. When you do, the browser will refresh and you’ll see your new component:

保存并关闭文件。 完成后,浏览器将刷新,您将看到新组件:

Your alert is rendering, so the next step is to style the component with CSS.

您的警报正在呈现,因此下一步是使用CSS设置组件样式。

将CSS添加到Alert组件 (Adding CSS to the Alert Component)

Since the Alert component dislays an error, you will add a border and set the color of the border to a shade of red. You’ll also give the <h2> tag the same color. But this presents a problem: You can’t use the name wrapper on the outer <div> in your Alert component, because that name is already taken by the App component.

由于Alert组件会显示错误,因此您将添加边框并将边框的颜色设置为红色阴影。 您还将为<h2>标记赋予相同的颜色。 但这带来了一个问题:您不能在Alert组件的外部<div>上使用名称wrapper ,因为该名称已被App组件使用。

Class name conflicts aren’t a new problem in CSS, and there have been a number of attempts to solve it using naming conventions such as BEM. But naming conventions can become verbose, and can still occasionally lead to conflicts in projects with a large number of components.

在CSS中,类名冲突并不是一个新问题,并且已经进行了许多尝试,例如使用BEM之类的命名约定来解决。 但是命名约定可能变得很冗长,并且有时仍会导致包含大量组件的项目发生冲突。

Rather than using a specific set of rules separated by naming convention, in this tutorial you will prefix the wrapper class name with the name of the component. Your new class name will be alert-wrapper. In addition, you will add the type of the alert as a class.

在本教程中,您将使用wrapper类名称的前缀作为组件名称,而不是使用由命名约定分隔的特定规则集。 您的新类名称将为alert-wrapper 。 另外,您将警报的type添加为类。

Open up the Alert component:

打开Alert组件:

  • nano src/components/Alert/Alert.js

    纳米src / components / Alert / Alert.js

Next, add the following highlighted code:

接下来,添加以下突出显示的代码:

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';
import PropTypes from 'prop-types';
import './Alert.css';
...
export default function Alert({ children, type, title }) {
  return(
    <div className={`alert-wrapper ${type}`}>
      <h2>{title}</h2>
      {children}
    </div>
  )
}
...

In this case, you’re combining alert-wrapper and the type variable into a single string using a template literal.

在这种情况下,您要使用模板literalalert-wrappertype变量组合为单个字符串。

Save and close the file. Now you have a unique class name that changes dynamically based on the prop. The JSX in this code will resolve to a div with the class names of alert-wrapper and error. The compiled mark up would be this: <div class="alert-wrapper error">.

保存并关闭文件。 现在,您有了一个唯一的类名称,该名称将根据prop动态更改。 此代码中的JSX将解析为具有alert-wrappererror的类名称的div 。 编译后的标记将是: <div class="alert-wrapper error">

Now add the styles. First, open the CSS for the Alert component:

现在添加样式。 首先,打开Alert组件CSS:

  • nano src/components/Alert/Alert.css

    纳米src / components / Alert / Alert.css

Add the following CSS to the alert-wrapper, success, and error classes:

将以下CSS添加到alert-wrappersuccesserror类中:

styling-tutorial/src/components/Alert/Alert.css
样式教程/src/components/Alert/Alert.css
.alert-wrapper {
    padding: 15px;
    margin-bottom: 15px;
}

.alert-wrapper h2 {
    margin: 0 0 10px 0;
}

.alert-wrapper.success {
    border: #6DA06F solid 1px;
}

.success h2 {
    color: #6DA06F;
}

.alert-wrapper.error {
    border: #F56260 solid 1px;
}

.error h2 {
    color: #F56260;
}

This code adds some margins and padding to the alert-wrapper. It then adds a border with a shade of red for the error class using the hexidecimal color code #F56260, and a shade of green (#6DA06F) for the success class. It also updates the <h2> color to red or green depending on the parent.

此代码为alert-wrapper添加了一些边距和填充。 然后,使用十六进制颜色代码 #F56260error类添加带有红色阴影的边框,为success类添加#6DA06F绿色阴影( #6DA06F )的#6DA06F 。 它还会根据父级将<h2>颜色更新为红色或绿色。

Save and close the file. When you do, the browser will refresh and you’ll see the new styles:

保存并关闭文件。 完成后,浏览器将刷新,您将看到新样式:

Now that you have a styled Alert component, you can create a new component that displays a list of items within the Alert component. Since the children will be more complex, there will be greater possibilities for style conflicts.

现在,您具有样式化的Alert组件,您可以创建一个新组件,该组件显示Alert组件中的项目列表。 由于孩子们会变得更加复杂,因此发生风格冲突的可能性会更大。

创建成功消息组件 (Creating a Success Message Component)

First, create a directory for for the new component CartSuccess:

首先,为新组件CartSuccess创建一个目录:

  • mkdir src/components/CartSuccess

    mkdir src / components / CartSuccess

Open CartSuccess.js:

打开CartSuccess.js

  • nano src/components/CartSuccess/CartSuccess.js

    纳米src / components / CartSuccess / CartSuccess.js

Inside the component, import the Alert component and pass a <div> containing a series of items that a user has added to the cart:

在组件内部,导入Alert组件并传递<div>其中包含用户已添加到购物车的一系列项目:

styling-tutorial/src/components/CartSuccess/CartSuccess.js
样式教程/src/components/CartSuccess/CartSuccess.js
import React from 'react';
import Alert from '../Alert/Alert';
import './CartSuccess.css';

export default function CartSuccess() {
  return(
    <Alert title="Added to Cart" type="success">
      <div className="cart-success-wrapper">
          <h2>
            You have added 3 items:
          </h2>
          <div className="item">
            <div>Bananas</div>
            <div>Quantity: 2</div>
          </div>
          <div className="item">
            <div>Lettuce</div>
            <div>Quantity: 1</div>
          </div>
      </div>
    </Alert>
  )
}

Notice how you needed to create a unique class name—cart-success-wrapper—for the outer <div>. Save and close the file.

请注意,您需要如何为外部<div>创建唯一的类名称-cart cart-success-wrapper 。 保存并关闭文件。

Next, add some CSS to the custom message. Open CartSuccess.css:

接下来,向自定义消息中添加一些CSS。 打开CartSuccess.css

  • nano src/components/CartSuccess/CartSuccess.css

    纳米src / components / CartSuccess / CartSuccess.css

Add a display of flex to the wrapper. You’ll want most of the items to wrap, except for the <h2> element, which should take up the whole width:

向包装器添加一个flex display 。 除了<h2>元素(该元素应占据整个宽度)外,您需要包装大多数物品:

styling-tutorial/src/components/CartSuccess/CartSuccess.css
样式教程/src/components/CartSuccess/CartSuccess.css
.cart-success-wrapper {
    border-top: black solid 1px;
    display: flex;
    flex-wrap: wrap;
}

.cart-success-wrapper h2 {
    width: 100%;
}

.item {
    margin-right: 20px;
}

Here, you gave the <h2> a width of 100%. In addition to flexing the element, you also added a small border to the top of the message, and added a margin to the item class to provide some space between items.

在这里,您给<h2>设置了100%的宽度。 除了弯曲元素之外,还在消息顶部添加了一个小边框,并在item类中添加了空白以在item之间提供一定的空间。

Save and close the file.

保存并关闭文件。

Now that you have a styled component, add it to your App component.

现在您有了样式化的组件,将其添加到您的App组件中。

Open App.js:

打开App.js

  • nano src/components/App/App.js

    纳米src / components / App / App.js

Import the component and add it after the current Alert component, as shown in the highlighted code:

导入组件并将其添加到当前Alert组件之后,如突出显示的代码所示:

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';
import './App.css';

import Alert from '../Alert/Alert';
import CartSuccess from '../CartSuccess/CartSuccess';

function App() {
  return(
    <div className="wrapper">
      <Alert title="Items Not Added" type="error">
        <div>Your items are out of stock.</div>
      </Alert>
      <CartSuccess />
    </div>
  )
}

export default App;

Save and close the file. When you do, the browser will refresh and you’ll see your new component:

保存并关闭文件。 完成后,浏览器将刷新,您将看到新组件:

This shows the new color and the message as intended, but the nested component received some unexpected styles. The rule for the <h2> in the Alert component is being applied to the nested <h2> tag in the children props.

这将按预期显示新的颜色和消息,但是嵌套的组件收到了一些意外的样式。 Alert组件中<h2>的规则已应用于children props中嵌套的<h2>标签。

Unexpected styles cascading to children are a common problem with CSS. However, since React gives you the opportunity to bundle and share components across projects, you have a greater potential for styles to inadvertently flow down to children components.

意外样式层叠到孩子是CSS的常见问题。 但是,由于React为您提供了在项目之间捆绑和共享组件的机会,因此您有更大的潜力使样式无意间流到子组件。

To fix this with pure CSS, make the <h2> rule for the Alert component a little more specific.

要使用纯CSS修复此问题,请使Alert组件的<h2>规则更加具体。

Open the Alert.css file:

打开Alert.css文件:

  • nano src/components/Alert/Alert.css

    纳米src / components / Alert / Alert.css

Change the rules so that the <h2> styling only applies to the direct children of the classes rather than all children using the CSS > child combinator:

更改规则,以使<h2>样式仅适用于类的直接子级,而不适用于所有使用CSS > child combinator的子级

styling-tutorial/src/components/Alert/Alert.css
样式教程/src/components/Alert/Alert.css
.alert-wrapper {
    padding: 15px;
    margin-bottom: 15px;
}

.alert-wrapper > h2 {
    margin: 0 0 10px 0;
}

.alert-wrapper.success {
    border: #6da06f solid 1px;
}

.success > h2 {
    color: #6da06f;
}

.alert-wrapper.error {
    border: #f56260 solid 1px;
}

.error > h2 {
    color: #f56260;
}

Save and close the file. When you do, the page will refresh and you’ll see the <h2> element in CartSuccess retain the default color:

保存并关闭文件。 完成后,页面将刷新,您会看到CartSuccess<h2>元素保留默认颜色:

Now the styles for the Alertcomponent will only affect the immediate children and will not apply to other child nodes or components. This method works well in this case, but in circumstances where components are more complex, it can be difficult to write rules that apply to all cases without leaking outside the component.

现在,“ Alert组件的样式将仅影响直接子对象,而不适用于其他子节点或组件。 这种方法在这种情况下效果很好,但是在组件更复杂的情况下,可能很难编写适用于所有情况的规则而又不会泄漏到组件外部。

In this step, you styled a component using CSS stylesheets imported directly into a component. Styling React elements with standard CSS is a quick way to create components with associated styles using standard CSS files. The ease of use makes it a good first step when you are working on new or small projects, but as the projects grow it can cause problems.

在此步骤中,您使用了直接导入到组件中CSS样式表为组件设置样式。 使用标准CSS样式化React元素是一种使用标准CSS文件创建具有关联样式的组件的快速方法。 易用性使您在处理新项目或小型项目时都迈出了良好的第一步,但是随着项目的发展,它可能会引起问题。

As you built the components, you encountered two common styling problems: class name conflicts and unintended style application. You can work around them with standard CSS, but there are other styling approaches that give you tools for handling these problems programmatically instead of with naming conventions. In the next step, you will explore solving these problems with style objects.

在构建组件时,遇到两个常见的样式问题:类名冲突和意外的样式应用程序。 您可以使用标准CSS来解决它们,但是还有其他样式设计方法可以为您提供以编程方式(而不是使用命名约定)来处理这些问题的工具。 在下一步中,您将探索使用样式对象解决这些问题。

步骤3 —使用样式对象进行样式设置 (Step 3 — Styling with Style Objects)

In this step, you’ll style your components using style objects, which are JavaScript objects that use CSS properties as keys. As you work on your components, you’ll update keys to match the JavaScript syntax and learn how to dynamically set style properties based on component props.

在此步骤中,您将使用样式对象来对组件进行样式设置样式 对象是使用CSS属性作为键的JavaScript对象 。 在处理组件时,将更新键以匹配JavaScript语法,并学习如何根据组件属性动态设置样式属性。

Separate CSS is the most common way to style HTML. This method is fast, and browsers are efficient at applying styles quickly and consistently. But this is not the only option for styling HTML. In standard HTML, you can set inline styles directly on an element using the style attribute with a string containing the styles you wanted to apply.

单独CSS是样式HTML的最常见方法。 这种方法速度很快,浏览器在快速而一致地应用样式方面效率很高。 但这不是样式HTML的唯一选择。 在标准HTML中,您可以使用style属性 (包含要应用的样式的字符串)直接在元素上设置内联样式。

One of the best uses of style objects is for calculating styles dynamically. This is particularly useful if you need to know the element’s current position, since this is not determined until the elements are rendered and thus can only be handled dynamically.

样式对象的最佳用途之一是动态计算样式。 如果您需要知道元素的当前位置,这将特别有用,因为只有在渲染元素之后才能确定该位置,因此只能动态处理该位置。

Writing style strings manually is difficult to do and can introduce bugs. A missing color or semicolon will break the entire string. Fortunately, in JSX, you aren’t limited to just a string. The style attribute can also accept an object containing the styles. These style names will need to be camelCase rather than kebab-case.

手动编写样式字符串很困难,并且可能会引入错误。 缺少颜色或分号将破坏整个字符串。 幸运的是,在JSX中,您不仅限于字符串。 样式属性还可以接受包含样式的对象。 这些样式名称将需要为camelCase而不是kebab-case

The biggest advantage to using inline styles like this is that, since you are building styles with JavaScript, you can dynamically set CSS properties instead of dynamically setting classes. This means you can write code without CSS classes at all, avoiding any potential name conflicts and allowing you to calculate styles at runtime.

使用这种内联样式的最大优点是,由于您正在使用JavaScript构建样式,因此可以动态设置CSS属性,而不是动态设置类。 这意味着您可以编写完全没有CSS类的代码,从而避免任何潜在的名称冲突,并允许您在运行时计算样式。

To use style objects, start by refactoring App.js. First, open the file:

要使用样式对象,请从重构App.js开始。 首先,打开文件:

  • nano src/components/App/App.js

    纳米src / components / App / App.js

Inside the component, remove the imported App.css file, and then create an object that has a padding of 20 and pass the object to the <div> using the style attribute:

在组件内部,删除导入的App.css文件,然后创建一个padding20的对象,然后使用style属性将该对象传递给<div>

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';

import Alert from '../Alert/Alert';
import CartSuccess from '../CartSuccess/CartSuccess';

function App() {
  const wrapper = {
    padding: 20
  };

  return(
    <div style={wrapper}>
      <Alert title="Items Not Added" type="error">
        <div>Your items are out of stock.</div>
      </Alert>
      <CartSuccess />
    </div>
  )
}

export default App;

Notice that you do not have to specify pixels as the unit for padding. React will convert this to a string of pixels by default. If you want a specific unit, pass it as a string. So if you wanted the padding to be a percentage for example, it would be padding: '20%'.

请注意,您不必将像素指定为padding的单位。 默认情况下,React会将其转换为像素字符串。 如果需要特定的单位,请将其作为字符串传递。 因此,例如,如果您希望填充为百分比,则为padding: '20%'

Most numbers will be automatically converted to pixels. There are exceptions, however. The property line-height can take plain numbers without a unit. If you wanted to use the pixels unit in that case, you’d need to specify pixels as a string.

大多数数字将自动转换为像素。 但是也有例外。 属性line-height可以采用不带unit的纯数字 。 如果要在这种情况下使用像素单位,则需要将像素指定为字符串。

Save and close the file. When you do, the browser will refresh and you’ll see the page as it was before:

保存并关闭文件。 完成后,浏览器将刷新,您将看到与以前一样的页面:

Next, refactor CartSuccess. First, open the file:

接下来,重构CartSuccess 。 首先,打开文件:

  • nano src/components/CartSuccess/CartSuccess.js

    纳米src / components / CartSuccess / CartSuccess.js

As with App.js, remove the imported CSS (CartSuccess.css) and create a style object for each item that previously had a class:

App.js ,删除导入CSS( CartSuccess.css )并为以前具有类的每个项目创建一个样式对象:

styling-tutorial/src/components/CartSuccess/CartSuccess.js
样式教程/src/components/CartSuccess/CartSuccess.js
import React from 'react';
import Alert from '../Alert/Alert';

export default function CartSuccess() {
  const styles = {
    header: {
      width: '100%'
    },
    item: {
      marginRight: 20
    },
    wrapper: {
      borderTop: 'black solid 1px',
      display: 'flex',
      flexWrap: 'wrap'
    }
  }

  return(
    <Alert title="Added to Cart" type="success">
      <div style={styles.wrapper}>
          <h2 style={styles.header}>
            You have added 3 items:
          </h2>
          <div style={styles.item}>
            <div>Bananas</div>
            <div>Quantity: 2</div>
          </div>
          <div style={styles.item}>
            <div>Lettuce</div>
            <div>Quantity: 1</div>
          </div>
      </div>
    </Alert>
  )
}

In this case, you didn’t create multiple, separate objects; instead, you created a single object that contains other objects. Notice also that you needed to use camel case for the properties of margin-right, border-top, and flex-wrap.

在这种情况下,您没有创建多个单独的对象。 相反,您创建了一个包含其他对象的对象。 还要注意,您需要对margin-rightborder-topflex-wrap的属性使用驼峰式大小写。

Save and close the file. When you do, the page will refresh and you’ll see the page with the same styles:

保存并关闭文件。 完成后,页面将刷新,您将看到具有相同样式的页面:

Since you are not using classes, you don’t have to worry about any name conflicts. Another advantage of creating styles with JavaScript is that you can take advantage of any JavaScript syntax such as variables and template literals. With modern CSS, you can use variables, which is a major improvement, but may not be fully available depending on your browser support requirements. In particular, they are not supported in any version of Internet Explorer, although you can use a polyfill to add support.

由于您没有使用类,因此您不必担心任何名称冲突。 使用JavaScript创建样式的另一个好处是,您可以利用任何JavaScript语法,例如变量和模板文字。 使用现代CSS,您可以使用variables ,这是一个重大改进,但是可能无法完全使用,具体取决于您的浏览器支持要求。 特别是,尽管您可以使用polyfill添加支持,但任何版本的Internet Explorer都不支持它们。

Since style objects are created at runtime, they are more predictable and can use any supported JavaScript.

由于样式对象是在运行时创建的,因此它们更具可预测性,并且可以使用任何受支持JavaScript。

To see how style objects can help in this situation, refactor Alert.js to use style objects. First, open Alert.js:

若要查看样式对象在这种情况下如何提供帮助,请重构Alert.js以使用样式对象。 首先,打开Alert.js

  • nano src/components/Alert/Alert.js

    纳米src / components / Alert / Alert.js

Inside Alert.js, remove import './Alert.css'; and create an object called colors that has a property for the error color and a property for the success color. Then convert the CSS to a JavaScript object using the type prop to dynamically set the color:

Alert.js内部,删除import './Alert.css'; 并创建一个名为colors的对象,该对象具有错误颜色的属性和成功颜色的属性。 然后使用prop type将CSS转换为JavaScript对象,以动态设置颜色:

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';
import PropTypes from 'prop-types';

export default function Alert({ children, type, title }) {
  const colors = {
    success: '#6da06f',
    error: '#f56260',
  }

  const style = {
    heading: {
      color: colors[type],
      margin: '0 0 10px 0',
    },
    wrapper: {
      border: `${colors[type]} solid 1px`,
      marginBottom: 15,
      padding: 15,
      position: 'relative',
    }
  }

  return(
    <div style={style.wrapper}>
      <h2 style={style.heading}>{title}</h2>
      {children}
    </div>
  )
}

...

There are a few changes here. First, you use a single style declaration for wrapper and then dynamically set the color based on the type. You are not styling <h2> elements in general, but instead are styling these particular elements, which happen to be <h2> elements. Since you are not applying styles to an element type, there is no danger that the styles will flow down to child elements.

这里有一些变化。 首先,对wrapper使用单个样式声明,然后根据类型动态设置颜色。 您一般不是在样式<h2>元素,而是在样式这些特殊元素,而这些元素恰巧是<h2>元素。 由于您没有将样式应用于元素类型,因此没有样式会流到子元素的危险。

Save and close the file. When you do, the browser will refresh and you’ll see the applied styles.

保存并关闭文件。 完成后,浏览器将刷新,您将看到应用的样式。

Style objects solve many problems, but they do have disadvantages. First, there is a performance cost for inline styles. Browsers were designed to handle CSS efficiently, and styles objects that apply inline styles can not take advantage of these optimizations. The other problem is that it’s more difficult to apply styles to child elements with style objects. In this case, you did not want a style to apply to children, but it is often the case that you do want styles to cascade. For example, setting a custom font family on every element or applying a custom size to every <h2> element would be easier if you used a less specific styling strategy.

样式对象解决了许多问题,但是它们确实有缺点。 首先, 内联样式会产生性能成本 。 浏览器旨在有效地处理CSS,并且应用内联样式的样式对象无法利用这些优化。 另一个问题是,将样式应用于带有样式对象的子元素更加困难。 在这种情况下,您不希望将样式应用于子项,但通常情况是您希望样式级联。 例如,如果使用不太具体的样式策略,则在每个元素上设置自定义字体系列或对每个<h2>元素应用自定义大小会更容易。

There is, however, a middle ground between these approaches. Several third-party libraries are designed to find this middle ground. In the next step, you’ll create styles using a hybrid approach called CSS-in-JS using a library called JSS.

但是,这些方法之间存在中间立场。 一些第三方库旨在找到这种中间立场。 在下一步中,您将使用称为JSS的库,使用称为CSS-in-JS的混合方法来创建样式。

第4步-使用JSS样式 (Step 4 — Styling with JSS)

In this step, you’ll style objects using the popular library JSS. You’ll install the new library and convert your style objects to JSS objects. You’ll then refactor your code to use dynamically generated class names that will prevent conflicts between class names across modules. You’ll also build JavaScript style objects that dynamically set styles and use nested properties to create specific style rules.

在这一步中,您将使用流行的库JSS为对象设置样式。 您将安装新的库并将样式对象转换为JSS对象。 然后,您将重构代码以使用动态生成的类名,这将防止跨模块的类名之间发生冲突。 您还将构建JavaScript样式对象,该对象可动态设置样式并使用嵌套属性创建特定的样式规则。

JSS is a library for creating CSS-in-JS. This methodology has many different use cases and options, but the main advantage in this tutorial is that it will create dynamic class names that avoid conflicts between components. You also will be able to take advantage of JavaScript syntax, which means you will be able to use variables and create styles based off of React props.

JSS是用于创建CSS-in-JS的库。 这种方法有许多不同的用例和选项 ,但是本教程的主要优点是它将创建动态的类名,从而避免组件之间的冲突。 您还将能够利用JavaScript语法,这意味着您将能够基于React道具使用变量并创建样式。

To begin, install the React specific version of JSS. This tutorial will use version 10.1.1:

首先,安装React的JSS特定版本 。 本教程将使用版本10.1.1

  • npm install react-jss

    npm安装react-jss

The package will install several dependencies, including a number of JSS plugins that will give you the ability to write concise style rules.

该软件包将安装几个依赖项,包括许多JSS插件 ,这些插件使您能够编写简洁的样式规则。

When the installation is complete, you’ll see a success message:

安装完成后,您将看到一条成功消息:


   
   
Output
+ react-jss@10.1.1 added 281 packages from 178 contributors, removed 142 packages, updated 1392 packages and audited 1025251 packages in 144.872s

Your output will vary slightly depending on your Node version and other dependencies.

您的输出将略有不同,具体取决于您的Node版本和其他依赖项。

Now that the library is installed, convert App.js to use JSS. First, open App.js:

现在已经安装了该库,将App.js转换为使用JSS。 首先,打开App.js

  • nano src/components/App/App.js

    纳米src / components / App / App.js

There are two steps to use JSS. First, you have to import a function to create a custom hook. Hooks are functions that React will run on every component render. With JSS, you have to create a hook by passing in the style definitions, outside of the component. This will prevent the code from running on every re-render; since the style definitions are static, there’s no reason to run the code more then once.

使用JSS有两个步骤。 首先,您必须导入一个函数来创建自定义钩子 。 挂钩是React可以在每个组件渲染器上运行的函数。 使用JSS,您必须通过在组件外部传入样式定义来创建钩子。 这样可以防止代码在每次重新渲染时运行; 由于样式定义是静态的,因此没有必要再运行一次代码。

Create the hook and the style object by making the highlighted changes:

通过进行突出显示的更改来创建钩子和样式对象:

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';
import { createUseStyles } from 'react-jss';

import Alert from '../Alert/Alert';
import CartSuccess from '../CartSuccess/CartSuccess';

const useStyles = createUseStyles({
  wrapper: {
    padding: 20,
  }
});

function App() {
  return(
    <div>
      <Alert title="Items Not Added" type="error">
        <div>Your items are out of stock.</div>
      </Alert>
      <CartSuccess />
    </div>
  )
}

export default App;

Notice in this case that your style object contains another object called wrapper, which contains the styles using the same camel case format. The name of the object—wrapper—is the basis for creating the dynamic class name.

请注意,在这种情况下,您的样式对象包含另一个名为wrapper对象,该对象包含使用相同驼峰大小写格式的样式。 对象的名称( wrapper是创建动态类名称的基础。

After you create the hook, you consume it by executing the function inside the component. This registers the hook and creates the styles dynamically. Make the following highlighted change:

创建钩子之后,可以通过在组件内部执行函数来使用它。 这将注册该钩子并动态创建样式。 进行以下突出显示的更改:

styling-tutorial/src/components/App/App.js
styling-tutorial / src / components / App / App.js
import React from 'react';
import { createUseStyles } from 'react-jss'

import Alert from '../Alert/Alert';
import CartSuccess from '../CartSuccess/CartSuccess';

const useStyles = createUseStyles({
  wrapper: {
    padding: 20,
  }
});

function App() {
  const classes = useStyles()
  return(
    <div className={classes.wrapper}>
      <Alert title="Items Not Added" type="error">
        <div>Your items are out of stock.</div>
      </Alert>
      <CartSuccess />
    </div>
  )
}

export default App;

In this code, you call the function and assign the results to a variable called classes. The new variable classes will be an object that contains the dynamic class names. You then apply the appropriate class name to your element by using the same name that you defined on the object. Here you used classes.wrapper.

在此代码中,您将调用函数并将结果分配给名为classes的变量。 新的变量classes将是一个包含动态类名称的对象。 然后,通过使用在对象上定义的相同名称,将适当的类名称应用于元素。 在这里,您使用了classes.wrapper

Save and close the file. When you do the browser will refresh and you’ll see the same styles as before. But if you look at the console, you’ll see that the class name does not perfectly match the one you defined in your object:

保存并关闭文件。 完成后,浏览器将刷新,您将看到与以前相同的样式。 但是,如果您查看控制台,您会发现类名与您在对象中定义的名称不完全匹配:

In this case, the class name is wrapper-0-2-1, but your class name may be different. You’ll also see that the styles are converted from an object to CSS and placed in a <style> tag. Contrast this to the inline styles, which are not converted to CSS and do not have any class names.

在这种情况下,类名是wrapper-0-2-1 ,但是您的类名可能不同。 您还将看到样式从对象转换为CSS并放置在<style>标记中。 将此与没有转换为CSS且没有任何类名的内联样式进行对比。

JSS creates the class names dynamically so they will not conflict with similar names in other files. To see this at work, refactor CartSuccess.js to use JSS styling.

JSS动态创建类名,因此它们不会与其他文件中的相似名冲突。 要在工作中看到此效果,请重构CartSuccess.js以使用JSS样式。

Open the file:

打开文件:

  • nano src/components/CartSuccess/CartSuccess.js

    纳米src / components / CartSuccess / CartSuccess.js

Inside the file, create a custom hook using createUseStyles. Instead of applying a class to the <h2> element, you’ll create a rule for the <h2> elements inside of a wrapper. To do that with plain CSS, you add a space between the class and the element—.wrapper h2. This applies the style to all <h2> elements that are children of the .wrapper class.

在文件内部,使用createUseStyles创建自定义钩子。 无需将类应用于<h2>元素,而是在包装器内为<h2>元素创建规则。 要使用普通CSS做到这一点,请在类和元素.wrapper h2之间添加一个空格。 这.wrapper样式应用于所有属于.wrapper类的子元素的<h2>元素。

With JSS, you can create a similar rule by creating another object inside of the containing element. To link them up, start the object name with the & symbol:

使用JSS,可以通过在包含元素内部创建另一个对象来创建类似的规则。 要链接它们,请以&符号开头对象名称:

styling-tutorial/src/components/CartSuccess/CartSuccess.js
样式教程/src/components/CartSuccess/CartSuccess.js
import React from 'react';
import { createUseStyles } from 'react-jss';
import Alert from '../Alert/Alert';

const useStyles = createUseStyles({
  item: {
    marginRight: 20
  },
  wrapper: {
    borderTop: 'black solid 1px',
    display: 'flex',
    flexWrap: 'wrap',
    '& h2': {
      width: '100%'
    }
  }
})

export default function CartSuccess() {
  const classes = useStyles();
  return(
    <Alert title="Added to Cart" type="success">
      <div className={classes.wrapper}>
          <h2>
            You have added 3 items:
          </h2>
          <div className={classes.item}>
            <div>Bananas</div>
            <div>Quantity: 2</div>
          </div>
          <div className={classes.item}>
            <div>Lettuce</div>
            <div>Quantity: 1</div>
          </div>
      </div>
    </Alert>
  )
}

In addition to creating rules for the wrapper, you also created a rule for item. After creating the custom hook, you passed the custom class names to the className property.

除了为包装器创建规则外,您还为item创建了规则。 创建自定义钩子后,将自定义类名称传递给className属性。

Save the file. Notice that you are using the same name—wrapper—in both this component and the App component. But when the browser reloads, there will be no naming conflict; everything will look correct. If you inspect the elements in your browser, you’ll see that even though they started with the same name, they each have a unique class:

保存文件。 请注意,在此组件和App组件中都使用了相同的名称,即wrapper 。 但是,当浏览器重新加载时,将不会有命名冲突。 一切都会看起来正确。 如果检查浏览器中的元素,即使它们以相同的名称开头,它们也将具有唯一的类:

In this case, the class for the outer component is wrapper-0-2-1, which was generated in the App component. The class for CartSuccess is wrapper-0-2-3. Your component names may be slightly different, but they will be unique.

在这种情况下,外部组件的类是wrapper-0-2-1 ,该类是在App组件中生成的。 CartSuccess的类为wrapper-0-2-3 。 您的组件名称可能会略有不同,但是它们将是唯一的。

In some situations, you may need to make a specific selector to override other styles. For example, let’s say you only want the item styling to apply when the element is a child of the wrapper class. To do this, first create the class on the object with no properties. Then inside the wrapper class, reference the new class with a $ symbol:

在某些情况下,您可能需要创建一个特定的选择器以覆盖其他样式。 例如,假设您只希望在元素是wrapper类的子级时应用item样式。 为此,首先在没有属性的对象上创建类。 然后在wrapper类中,使用$符号引用新类:

styling-tutorial/src/components/CartSuccess/CartSuccess.js
样式教程/src/components/CartSuccess/CartSuccess.js
import React from 'react';
import { createUseStyles } from 'react-jss'
import Alert from '../Alert/Alert';

const useStyles = createUseStyles({
  item: {},
  wrapper: {
    borderTop: 'black solid 1px',
    display: 'flex',
    flexWrap: 'wrap',
    '& h2': {
      width: '100%'
    },
    '& $item': {
      marginRight: 20
    }
  }
})

export default function CartSuccess() {
  const classes = useStyles()
  return(
    <Alert title="Added to Cart" type="success">
      <div className={classes.wrapper}>
          <h2>
            You have added 3 items:
          </h2>
          <div className={classes.item}>
            <div>Bananas</div>
            <div>Quantity: 2</div>
          </div>
          <div className={classes.item}>
            <div>Lettuce</div>
            <div>Quantity: 1</div>
          </div>
      </div>
    </Alert>
  )
}

Save and close the file. When the browser reloads, the page will look the same, but the item CSS will be applied more specifically to items under the wrapper component:

保存并关闭文件。 当浏览器重新加载时,页面看起来将相同,但是CSS item将更具体地应用于包装器组件下的项目:

JSS gives you the ability to create rules with the same level of focus that you’d create with regular CSS, but will do so while creating unique class names that won’t clash.

JSS使您能够创建具有与常规CSS相同级别的焦点的规则,但是会在创建不会冲突的唯一类名时这样做。

One final advantage of JSS is that you have the ability to use variables and other JavaScript language features. Since you are using react-jss, you can pass props to the style object to create dynamic styles. To test this out, refactor the Alert.js component to use props and variables to create dynamic properties.

JSS的最后一个优势是您可以使用变量和其他JavaScript语言功能。 由于您正在使用react-jss ,因此可以将react-jss传递给样式对象以创建动态样式。 为了测试这一点,请重构Alert.js组件以使用道具和变量来创建动态属性。

First, open the file:

首先,打开文件:

  • nano src/components/Alert/Alert.js

    纳米src / components / Alert / Alert.js

Create a style object like you did in the last refactored code. Be sure to move the object defining the colors outside of the component function so it is in the same scope as the createUseStyles function:

像在上一个重构代码中一样创建一个样式对象。 确保将定义颜色的对象移到component函数之外,以便它与createUseStyles函数处于同一范围内

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';
import PropTypes from 'prop-types';
import { createUseStyles } from 'react-jss';

const colors = {
  success: '#6da06f',
  error: '#f56260',
};

const useStyles = createUseStyles({
    wrapper: {
      border: ({ type }) => `${colors[type]} solid 1px`,
      marginBottom: 15,
      padding: 15,
      position: 'relative',
      '& h2': {
        color: ({ type }) => colors[type],
        margin: [0, 0, 10, 0],
      }
    }
});

export default function Alert({ children, type, title }) {
  const classes = useStyles({ type })
  return(
    <div className={classes.wrapper}>
      <h2>{title}</h2>
      {children}
    </div>
  )
}

...

To pass props, you make the style rule a function. The function accepts the props as an argument then returns a rule. To create a dynamic border, you add border as the property name and an arrow function that takes type and returns a string: ({ type }) => `${colors[type]} solid 1px`,. Then after you create your hook, you pass in the props you want to reference when creating the classes object. As before, you style the <h2> tag by element instead of creating a specific class. You also pass an array of values for margin rather than a string such as 0px 0px 10px 10px.

要传递道具,请使样式规则成为一个函数。 该函数接受props作为参数,然后返回规则。 要创建动态边框,请添加border作为属性名称,并添加一个接受type并返回字符串的箭头函数({ type }) => `${colors[type]} solid 1px`, 然后,在创建钩子之后,传入创建类对象时要引用的道具。 和以前一样,您可以按元素设置<h2>标记的样式,而不是创建特定的类。 您还传递了一个用于margin的值数组,而不是一个字符串,例如0px 0px 10px 10px

Save the file. Notice that you don’t have to pass all the props into the function. In this case, you only want to use type, so that’s all you need to pass. However, you can pass more or even pass unknown props using the rest operator to collect props and then pass them as a group. You do need to pass it as an object; however, since that’s the standard way to pass props, it will make extending the arguments easier in the future.

保存文件。 注意,您不必将所有道具传递给函数。 在这种情况下,您只想使用type ,这就是您需要传递的所有内容。 但是,您可以使用rest运算符传递更多甚至传递未知的道具,以使用其余操作符收集道具,然后将它们作为一个组传递。 您确实需要将其作为对象传递; 但是,由于这是传递道具的标准方法,因此将来会使扩展参数变得更加容易。

When the page reloads, you’ll see the correct colors, but there will be a slight problem: the green success color is now updating the <h2> element in CartSuccess:

重新加载页面时,您将看到正确的颜色,但是会有一个小问题:绿色成功颜色现在正在更新CartSuccess<h2>元素:

JSS solves many problems, but it still creates standard CSS. That means that styles can apply to child elements if you are not careful. To fix this, add the > symbol to make the CSS only apply to immediate children:

JSS解决了许多问题,但仍创建标准CSS。 这意味着如果您不小心,样式可以应用于子元素。 要解决此问题,请添加>符号以使CSS仅适用于直接子代:

styling-tutorial/src/components/Alert/Alert.js
样式教程/src/components/Alert/Alert.js
import React from 'react';
...
const useStyles = createUseStyles({
    wrapper: {
      border: ({ type }) => `${colors[type]} solid 1px`,
      marginBottom: 15,
      padding: 15,
      position: 'relative',
      '& > h2': {
        color: ({ type }) => colors[type],
        margin: [0, 0, 10, 0],
      }
    }
});

export default function Alert({ children, type, title }) {

...

}

...

Save and close the file. When you do the browser will reload and you’ll see the correct styles:

保存并关闭文件。 完成后,浏览器将重新加载,您将看到正确的样式:

There is much more to JSS beyond what is covered in this tutorial. One important advantage that we haven’t touched on is theming. JSS gives you the ability to create styles based off of pre-defined theme objects. That means that instead of creating a color red from a hard coded value, you can make the alert border the alert color, which will likely be a shade of red, but could be different depending on the theme definition. This is useful when creating white label products or creating reusable components that need to work across projects.

除了本教程介绍的内容外,JSS还有很多其他功能。 我们尚未谈到的一个重要优点是主题化 。 JSS使您能够基于预定义的主题对象创建样式。 这意味着您可以使警报边界成为alert颜色,而不是根据硬编码值创建红色,该alert颜色可能是红色阴影,但根据主题定义而有所不同。 在创建白标产品或创建需要跨项目使用的可重用组件时,这很有用。

In this step, you styled components using a third-party library called react-jss. You also created style object and used JSS to convert those objects into dynamic classes to avoid conflicting with other components. Using this method, you can safely reuse simple class names without worrying about conflicts later in the code. Finally, you learned how to create styles using functions and props to build dynamic styles that reference component props.

在此步骤中,您使用名为react-jss的第三方库react-jss组件进行样式设置。 您还创建了样式对象,并使用JSS将这些对象转换为动态类,以避免与其他组件发生冲突。 使用此方法,您可以安全地重用简单的类名,而不必担心稍后代码中的冲突。 最后,您学习了如何使用函数和道具创建样式来构建引用组件道具的动态样式。

结论 (Conclusion)

Throughout this tutorial, you have developed several reusable components that use different style techniques. You’ve learned how style objects and JSS create objects using names that closely mirror standard CSS properties, and have created components that can dynamically set styles based on incoming properties. You also learned how different approaches provide different options for handling name conflicts and reusability.

在本教程中,您已经开发了几个使用不同样式技术的可重用组件。 您已经了解了样式对象和JSS如何使用与标准CSS属性非常相似的名称创建对象,并创建了可以根据传入属性动态设置样式的组件。 您还了解了不同的方法如何为处理名称冲突和可重用性提供不同的选项。

As with most React techniques, there is no single best solution. Instead, you can choose the styling option that is the best fit for your project. With these options in hand, you can start with something simple and refactor as the project grows or the requirements change, while remaining confident that your components will continue to meet your style goals.

与大多数React技术一样,没有单一的最佳解决方案。 相反,您可以选择最适合您的项目的样式选项。 有了这些选项,您可以从简单的事情开始,并随着项目的发展或需求的变化进行重构,同时对组件将继续满足样式目标充满信心。

If you would like to look at more React tutorials, check out our React Topic page, or return to the How To Code in React.js series page.

如果您想查看更多React教程,请查看我们的React Topic页面 ,或者返回到React.js系列中How To Code页面

翻译自: https://www.digitalocean.com/community/tutorials/how-to-style-react-components

react 组件样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值