一、组件
定义组件的两种方式
1.函数组件
const Ren = function () {
return (<div>奥特曼</div>)
}
2.类组件
class Head extends Component {
render () {
return (
<div>我是封装出来的组件</div>
)
}
}
使用的话直接当成标签来用就好了 注意首字母大写哈
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Ren />
<Head></Head>
</React.StrictMode>
)
二、父传子
定义形式 <组件名 属性名=属性值></组件名>
import React, { Component } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
import SonFirst from './02、子组件1'
import SonSecond from './02、子组件2'
import Third from './02、子组件3'
class Father extends Component {
state = {
userInfo: {
name: '奥特曼'
},
tags: <h1>奥特曼</h1>
}
render () {
return (
<div>
我是父组件 class类
{/* 定义形式 属性名=属性值 */}
<SonFirst num={1}></SonFirst>
<SonSecond userInfo={this.state.userInfo}></SonSecond>
<Third tags={this.state.tags}></Third>
</div >
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Father />
</React.StrictMode>
)
类组件接收
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
export default class Son extends Component {
render () {
return (
<div>
{this.props.num}
我是子组件
</div>
)
}
}
通过 this.props.num 接收
函数组件接收
/* eslint-disable react/prop-types */
import React from 'react'
export default function Son (props) {
return (
// eslint-disable-next-line react/prop-types
<div>
{props.num}
我是函数的子组件
</div>
)
}
事件参数 第一个参数就是 props对象
props 可以传递 数字、字符串、布尔类型、数组、对象、函数、jsx
不可以直接修改 props穿过来的值 若想修改 可以传递方法 去修改父组件的值
传递jsx
父
import Son from './04、子组件'
export default class Father extends Component {
render () {
return (
<div>
<Son>
<h1>奥特曼噢噢噢噢~~</h1>
</Son>
</div>
)
}
}
子
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
// props的children 类似于 slot 插槽·
export default class Son extends Component {
render () {
console.log(this.props)
return (
<div>
{this.props.children}
</div>
)
}
}
子组件可以直接去使用哈
传递方法demo
父
import React, { Component } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
import Son from './05、子组件'
class Father extends Component {
state = {
list: [{ id: 1, name: '迪迦', num: 10, price: 9 }, { id: 2, name: '雷欧', num: 5, price: 10 }, { id: 3, name: '泰罗', num: 6, price: 7 }],
allPrice: 0
}
accPrice = (price) => {
console.log(price, this.state.allPrice)
this.setState({
allPrice: this.state.allPrice + price
})
}
addNum = (idx) => {
let arr = [...this.state.list]
arr[idx].num++
this.setState({
arr
})
}
render () {
const { list } = this.state
return (
<>
{list.map((it, idx) => {
return <Son accPrice={this.accPrice} addNum={this.addNum} idx={idx} info={it} key={it.id}></Son>
})}
<div>总价:{list.reduce((acc, it) => acc + it.num * it.price, 0)}</div>
</>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Father />
</React.StrictMode>
)
子
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
export default class Son extends Component {
add = () => {
console.log(this.props)
this.props.addNum(this.props.idx)
}
render () {
console.log(this.props)
const { info, idx } = this.props
// this.props.accPrice(info.price * info.num)
return (
<div>
<div style={{ padding: '20px', width: '400px', border: '1px solid #000' }}>
<div >
<div> 名字: {info.name}</div>
<div> 数量: {info.num} <button onClick={this.add}>+1</button> </div>
<div> 价钱: {info.price}</div>
<div> 总价: {info.price * info.num} </div>
</div>
</div >
</div>
)
}
}
props的三个特点:
1.可以传任何内容
2.只读的,不可以直接修改
3.遵守单项数据流原则(一层一层往下传)
三、兄弟传值
兄弟传值 a组件使用父组件的值 b组件通过父组件的传递过来的方法进行修改 没有像vue中的vuex、eventbus
父
import React, { Component } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
import Son1 from './06、兄弟1'
import Son2 from './06、兄弟2'
class Father extends Component {
state = {
num: 1
}
addNum = () => {
this.setState({
num: this.state.num + 1
})
}
render () {
const { list } = this.state
return (
<>
<Son1 addNum={this.addNum} ></Son1>
<Son2 num={this.state.num}></Son2>
</>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Father />
</React.StrictMode>
)
子1
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
export default class SON extends Component {
add = () => {
this.props.addNum()
}
render () {
return (
<div>
<button onClick={this.add}>数量加1</button>
</div>
)
}
}
子2
/* eslint-disable react/prop-types */
import React, { Component } from 'react'
export default class SON extends Component {
render () {
return (
<div>
{this.props.num}
</div>
)
}
}
四、跨级传值
使用方法
1. 导入并调用createContext方法 从结果中结构出 provider,consumer 组件
import React, { createContext } from 'react'
const { Provider, Consumer } = createContext()
2. 使用Provider 组件包裹根组件 并通过value属性提供要共享的数据
return (
<Provider value={ 传递的数据 }>
<根组件的内容 />
</Provider>
)
记得导出 export { Consumer }
3.在任意后代组件中 使用第1步导出Consummer组件 在包裹住整个组件
import { Consumer } from './07、跨级传值'
export default class Parent extends React.Component {
render () {
return (
<Consumer>
{
(data) => {
console.log(data)
return (
<>
内容
</>
)
}
}
</Consumer>)
}
}
demo
顶层组件
import React, { Component, createContext } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
const { Provider, Consumer } = createContext()
import Fathers from './07、子组件'
class Grandpa extends Component {
state = {
num: 1
}
addNum = (number) => {
this.setState({
num: this.state.num + number
})
}
render () {
return (
<>
<Provider value={{ num: this.state.num, add: this.addNum }}>
<Fathers></Fathers>
</Provider>
</>
)
}
}
export { Consumer }
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Grandpa />
</React.StrictMode>
)
父组件
import React from 'react'
import ReactDOM from 'react-dom'
import Son from './07、孙组件'
import { Consumer } from './07、跨级传值'
export default class Parent extends React.Component {
state = {
num: 1
}
addNum = () => {
this.setState({
num: this.state.num + 1
})
}
render () {
return (
<Consumer>
{
(data) => {
console.log(data)
return (
<>
<div onClick={() => data.add(100)}>我是Father组件-{data.num}</div>
<Son></Son>
</>
)
}
}
</Consumer>)
}
}
子组件
import React, { Component, createContext } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
import { Consumer } from './07、跨级传值'
export default class Son extends Component {
state = {
num: 1
}
addNum = () => {
this.setState({
num: this.state.num + 1
})
}
render () {
return (
<Consumer>
{
(data) => {
console.log(data)
return (
<div onClick={() => data.add(100)}>我是son组件-{data.num}</div>
)
}
}
</Consumer>)
}
}
抽离跨级组件
import React from 'react'
const { Provider, Consumer } = React.createContext()
export { Provider, Consumer }
父组件
import React, { Component, createContext } from 'react'
import ReactDOM from 'react-dom/client' //配合ceact把react 元素渲染到dom
import { Provider } from './08、context'
import Son from './08、子组件'
class Father extends Component {
state = {
num: 1
}
addNum = () => {
this.setState({
num: this.state.num + 1
})
}
render () {
return (
<>
<Provider value={this.state.num}>
<Son></Son>
</Provider>
</>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Father />
</React.StrictMode>
)
子组件
import { Consumer } from './08、context'
import React, { Component } from 'react'
export default class Son extends Component {
render () {
return (
<Consumer>
{
(data) => {
return (
<>
<div onClick={() => data.add(100)}>我是Son组件-{data}</div>
</>
)
}
}
</Consumer>)
}
}
推荐插件
在项目中 打出rcc rfc 就可以 快捷创建代码啦
rcc: create class Componet
rfc: create function Componet