严格模式检查什么?

  1. ReactDOM.render(
  2. <React.StrictMode>
  3. <App />
  4. </React.StrictMode>,
  5. document.getElementById('root')
  6. );

React.StrictMode 标签内的子组件都开启了严格模式

  • 识别不安全的声明周期
  • 检查使用过时的ref API
  • 检查意外的副作用(开发环境中constructor会被调用2次)
  • 检查使用废弃的findDOMNode方法
  • 检查过时的context API

可根据个人喜好选择是否开启严格模式

React中的样式

组件化框架中CSS解决方案应符合下列条件:

  • 可以编写局部CSS, 具备局部作用域
  • 可以变形动态CSS
  • 支持所有的CSS特性:伪类、动画、媒体查询
  • 简洁方便,符合一贯CSS风格

React 官方没有给出标准的解决方案

内联样式

内联样式是把CSS以对象形式赋值给style, 属性名用驼峰式,px单位可省略

内联样式缺点:

  • 定义变量时没有代码提示
  • 大量内联样式会造成代码混乱
  • 无法编写伪类/伪元素 ```jsx const pStyle = { color: “pink”, textDecoration: “underscore” }

const App = () => { return (

我是一只鱼

我喜欢游泳

) }

export default App

  1. <a name="AnVQj"></a>
  2. #### 普通CSS
  3. 写普通CSS的目录结构如下图所示<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1753813/1643190093416-49068e30-0b60-41da-b9df-21ec9e9362ce.png#clientId=ub3281eb4-3950-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=273&id=u4b4eafb7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=341&originWidth=445&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23199&status=done&style=none&taskId=ue43ea3f6-ba6b-4742-af94-44db47cccdb&title=&width=356)<br />由于 webpack 的特性,import 的时候只需要写文件夹,默认会去寻找 index.js 文件
  4. ```javascript
  5. import Home from "../home"
  6. import Profile from "../profile"
  7. import './style.css'
  8. const App = () => {
  9. return (
  10. <div>
  11. <h1 className="title">我是App</h1>
  12. <p>哈哈哈哈哈哈哈</p>
  13. <Home />
  14. <Profile />
  15. </div>
  16. )
  17. }
  18. export default App

普通CSS的缺点是:
由于CSS的层叠特性,不同组件的CSS会相互覆盖,必须写非常复杂的选择器才能解决相互覆盖问题

CSS modules

CSS modules不是React特有的解决方案,在所有类webpack配置的环境下都可以使用
React的脚手架已经内置了css modules的配置:

  • .css/.less/.scss 等样式文件都修改成 .module.css/.module.less/.module.scss等
  • 模块化引入后即可使用

CSS modules解决了局部作用域问题,是在React中比较受欢迎的一种方案,有时也要配合内联样式一起使用
image.png
style.module.css

  1. .title {
  2. color: gold;
  3. }
  4. .new-p {
  5. color: blue;
  6. }

index.js

  1. import style from './style.module.css'
  2. const App = () => {
  3. return (
  4. <div>
  5. <h1 className={style.title}>我是App</h1>
  6. <p className={style['new-p']}>哈哈哈哈哈哈哈</p>
  7. </div>
  8. )
  9. }

可以看到 class 都被加上了唯一性的 hash 后缀
image.png

CSS in JS

CSS-in-JS通过JavaScript为CSS赋予一些能力,包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用等
目前比较流行的CSS-in-JS库有:

  • styled-components
  • emotion
  • glamorous

目前styled-components依然是社区最流行的CSS-in-JS库

安装styled-components

  1. yarn add styled-components

安装 VSCode 插件高亮 styled-components 代码
image.png

带标签的模板字符串

styled-components的本质实际上是通过模板字符串的方式调用函数,函数解析````中传入的参数,返回React组件

  1. const fn = (...args) => {
  2. console.log(args)
  3. }
  4. const a = 'apple'
  5. const b = 'banana'
  6. // 通过模板字符串的方式调用函数
  7. fn`hello ${a}, I love ${b}`

可以看到传入的参数被解析成了数组
image.png

styled-components的基本使用

可使用与scss类似的嵌套语法
style.js

  1. import styled from "styled-components"
  2. export const AppWrapper = styled.div`
  3. .title {
  4. font-size: 24px;
  5. color: red;
  6. &:hover {
  7. color: blue;
  8. }
  9. &::after {
  10. content: 'aa'
  11. }
  12. }
  13. `

index.js

  1. import Home from "../home"
  2. import Profile from "../profile"
  3. import { AppWrapper } from "./style"
  4. const App = () => {
  5. return (
  6. <AppWrapper>
  7. <h1 className="title">我是App</h1>
  8. <p className="haha">哈哈哈哈哈哈哈</p>
  9. <Home />
  10. <Profile />
  11. </AppWrapper>
  12. )
  13. }
  14. export default App

props 穿透

给styled-component添加的属性会作用在根元素上

  1. const Input = styled.input`
  2. background-color: lightblue;
  3. border: 1px solid yellow;
  4. `
  5. <Input type="password" placeholder="hello"/>

attrs

styled还可以通过调用.attrs方法给组件设置属性

  1. const BInput = styled.input.attrs({
  2. placeholder: "banana"
  3. })`
  4. color: red;
  5. font-size: 16px;
  6. `

模板字符串中的props

在styled内部可以通过模板字符串中的 props 获取到 props 穿透 或 attrs 中的属性值,一般写成箭头函数的形式

  1. const BInput = styled.input.attrs({
  2. placeholder: "banana",
  3. bgColor: "blue",
  4. })`
  5. background-color: ${props => props.bgColor};
  6. color: ${props => props.color};
  7. font-size: ${props => props.fontSize}
  8. `
  9. <BInput fontSize="24px" color="red"/>

继承
  1. const Input = styled.input`
  2. background-color: lightblue;
  3. border: 1px solid yellow;
  4. `
  5. // 继承Input组件的样式
  6. const CInput = styled(Input)`
  7. font-size: 30px;
  8. color: red;
  9. `

Theme

styled-components提供了ThemeProvider组件,可以将它的theme属性中的值传递给所有的子组件,子组件通过props获取到这些属性值

  1. const Button = styled.button`
  2. background-color: ${props => props.theme.blueColor};
  3. color: ${props => props.theme.fontColor}
  4. `
  5. const App = () => (
  6. <ThemeProvider theme={{blueColor: "lightBlue", fontColor: "pink"}}>
  7. <Button>hello</Button>
  8. </ThemeProvide>
  9. )