React中處理樣式的五種方法
關(guān)注公眾號(hào) 前端人,回復(fù)“加群”
添加無(wú)廣告優(yōu)質(zhì)學(xué)習(xí)群
行內(nèi)樣式
const styleApp = {
fontSize: 20,
color: 'red',
}
export default class App extends React.Component {
render() {
return (
<h1 style={ styleApp }>首頁(yè)面</h1>
)
}
}
note
行內(nèi)樣式使用對(duì)象賦值
外部樣式
新建一個(gè)CSS文件, 在JS文件中引入 CSS文件
import "./App.css"
CSS的模塊化
CSS的模塊化命名必須是 xxx.module.css
xxx.module.css 中的代碼如下:
.error{
color: red;
font-weight: bold;
}
使用:
引入
import common from "./css/common.module.css"使用
<h1 className={ common.error }>錯(cuò)誤信息
根據(jù)不同的條件添加不同的樣式
這里我們使用 classnames 這個(gè)包
安裝 npm i classnames
引入 : import classNames from 'classnames';
舉個(gè)例子
import React, { Component } from 'react'
import classNames from "classnames"
// 引入外部樣式
import "./App.css"
export default class App extends Component {
render() {
let h1Class = classNames({
'box1':true,
'box2':true
})
return (
<div className="container">
<h1 className={ h1Class }>這是一個(gè)盒子</h1>
</div>
)
}
}
復(fù)制代碼
styled-components & css in js
安裝:
npm i styled-components -S
所謂 css in js, 就是在 js 中寫css.
創(chuàng)建一個(gè) style.js 文件:
import styled from "styled-components"
// 創(chuàng)建一個(gè) Container 組件,它將渲染一個(gè)附加了樣式的 <div> 標(biāo)簽
let Container = styled.div`
width:500px;
height:500px;
background:${ (props)=>props.color };
font-size:30px;
h1{
color:blue
}
`
export {
Container
}
在需要使用的地方先引入該組件,然后當(dāng)成標(biāo)簽使用,代碼如下:
import React, { Component } from 'react'
import { Container } from "./style"
export default class Search extends Component {
render() {
return (
<Container color='gold'>
<h1>Helo React~</h1>
</Container>
)
}
}
復(fù)制代碼
組件間通信
React是以組件組合的形式組織的。所以在嵌套關(guān)系上,就會(huì)有四種不同的可能性:
父組件向子組件通信
子組件向父組件通信
沒有嵌套關(guān)系的組件通信
跨級(jí)組件通信
父組件向子組件通信
class ListItem extends Component {
constructor(props) {
super(props);
this.value = this.props.value;
}
render() {
return (
<li>
<span>{this.value}</span>
</li>
)
}
}
export default class App extends Component {
render() {
const list = [1, 2, 3, 4, 5];
return (
<ul>
{list.map((entry, index) => (
<ListItem key={`list-${index}`} value={entry}/>
))}
</ul>
)
}
}
復(fù)制代碼
子組件向父組件通信
在用React之前的組件開發(fā)模式時(shí),常常需要接收組件運(yùn)行時(shí)的狀態(tài),這時(shí)我們的方法有:
利用回調(diào)函數(shù)
父組件將一個(gè)函數(shù)作為props傳遞給子組件,子組件調(diào)用該回調(diào)函數(shù),便可以向父組件通信
利用自定義事件機(jī)制
舉個(gè)例子
class Child extends Component {
constructor(props) {
super(props);
this.state = {
msg: '子組件的msg傳值'
}
}
// 通過(guò)props 調(diào)用回調(diào)函數(shù)傳值
trans = () => {
this.props.callback(this.state.msg);
}
render() {
return (
<div>
<button onClick={this.trans}>傳值給父組件</button>
</div>
)
}
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
msg: '父組件初始msg'
}
}
// 父組件回調(diào)函數(shù),更新state,進(jìn)而更新父組件
callback = (msg) => {
console.log(msg);
// setState方法,修改msg參數(shù),值是由子組件傳過(guò)來(lái)的
// this.setState({ msg })
}
render() {
return (
<div className="App">
<p>{this.state.msg}</p>
<Child callback={this.callback}/>
</div>
)
}
}
復(fù)制代碼
沒有嵌套關(guān)系的組件通信
我們就常以 發(fā)布/訂閱模式來(lái)舉例子, 這里我們用 node.js Events模塊來(lái)實(shí)現(xiàn)。
好像就是vue中的EventBus方法
note 我們?cè)谔幚硎录倪^(guò)程中需要注意, componentDidMount 事件中, 如果組件掛載完成, 再訂閱事件; 當(dāng)組件卸載的時(shí)候, 在componentWillUnmount 事件中取消事件的訂閱。
安裝events并引入
1. npm i events --save
2. 新建 Evt.js 導(dǎo)入 events
import { EventEmitter } from 'events'
export default new EventEmitter();
具體是這樣的
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
import emitter from './Evt.js';
export default class App extends Component {
handleClick = () => {
emitter.emit('call', 'hello world');
}
render() {
return (
<div>
<button onClick={this.handleClick}>點(diǎn)擊</button>
<Custom1/>
</div>
)
}
}
class Custom1 extends Component {
constructor(props) {
super(props);
this.state = {
msg: ''
}
}
componentDidMount() {
emitter.addListener('call', (msg) => {
this.setState({ msg })
})
// emitter.removeListener('call');
}
componentWillUnmount() {
emitter.removeListener('call');
}
render() {
return (
<p style={{color:'red'}}>
{this.state.msg}
</p>
)
}
}
跨級(jí)組件通信
所謂跨級(jí)組件通信,就是父組件向子組件的子組件通信, 向更深層的子組件通信。一般來(lái)說(shuō)有以下兩種方法:
中間組件層層傳遞props
使用context對(duì)象
使用context需要滿足兩個(gè)條件:
上級(jí)組件要聲明自己支持 context, 并提供一個(gè)函數(shù)來(lái)返回相應(yīng)的 context對(duì)象
子組件要聲明自己需要使用 context
下面我們舉個(gè)例子, 新建三個(gè)文件:
App.js 父組件
Sub.js 子組件
SubSub.js 子組件的子組件
App.js
import React, { Component } from 'react';
import PropTypes from "prop-types";
import Sub from "./Sub";
import "./App.css";
export default class App extends Component{
// 父組件聲明自己支持 context
static childContextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
// 父組件提供一個(gè)函數(shù),用來(lái)返回相應(yīng)的 context 對(duì)象
getChildContext(){
return{
color:"red",
callback:this.callback.bind(this)
}
}
callback(msg){
console.log(msg)
}
render(){
return(
<div>
<Sub></Sub>
</div>
);
}
}
Sub.js
import React from "react";
import SubSub from "./SubSub";
const Sub = (props) =>{
return(
<div>
<SubSub />
</div>
);
}
export default Sub;
SubSub.js
import React,{ Component } from "react";
import PropTypes from "prop-types";
export default class SubSub extends Component{
// 子組件聲明自己需要使用 context
static contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
render(){
const style = { color:this.context.color }
const cb = (msg) => {
return () => {
this.context.callback(msg);
}
}
return(
<div style = { style }>
SUBSUB
<button onClick = { cb("我胡漢三又回來(lái)了!") }>點(diǎn)擊我</button>
</div>
);
}
}
復(fù)制代碼
有幾點(diǎn)需要注意:
父組件需要聲明自己支持 context,并提供context中屬性的 PropTypes
static childContextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
復(fù)制代碼
子組件需要聲明自己需要使用 context,并提供其需要使用的 context 屬性的 PropTypes
static contextTypes = {
color:PropTypes.string,
callback:PropTypes.func,
}
復(fù)制代碼
父組件需提供一個(gè) getChildContext 函數(shù),以返回一個(gè)初始的 context 對(duì)象
原文:juejin.cn/post/6931717995576164365
回復(fù) 資料包領(lǐng)取我整理的進(jìn)階資料包回復(fù) 加群,加入前端進(jìn)階群console.log("文章點(diǎn)贊===文章點(diǎn)在看===你我都快樂")Bug離我更遠(yuǎn)了,下班離我更近了

