目录:
setState更新状态的2种写法
Demo.jsx
- import React, {Component} from 'react';
-
- class Demo extends Component {
- state = {count: 0}
-
- add = () => {
- //对象式的setState
- // const {count} = this.state
- // this.setState({count: count + 1}, () => {
- // console.log(this.state.count)
- // })
- // // console.log('12行的输出', this.state.count)
-
-
- //函数式的setState
- // this.setState((state, props) => {
- // console.log(state, props)
- // return {count: state.count + 1}
- // })
-
- this.setState(state => ({count: state.count + 1}), () => {
- console.log(this.state.count)
- })
-
- // this.setState({count: this.state.count + 1})
- }
-
- render() {
- return (
-
-
当前求和为:{this.state.count}
-
-
- );
- }
- }
-
- export default Demo;
路由组件的lazyLoad
- //1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
- const Login = lazy(()=>import('@/pages/Login'))
-
- //2.通过
指定在加载得到路由打包文件前显示一个自定义loading界面 -
loading.....}> -
-
"/xxx" component={Xxxx}/> -
"/login"/> -
-
About.jsx
- import React, {Component} from 'react';
-
- class About extends Component {
- render() {
- return (
-
-
我是About的内容
-
- );
- }
- }
-
- export default About;
Demo.jsx
- import React, {Component, lazy, Suspense} from 'react';
- import {NavLink, Route} from "react-router-dom";
- import Loading from "../Loading/Loading";
-
- const Home = lazy(() => import('../Home/Home'))
- const About = lazy(() => import('../About/About'))
-
-
- class Demo extends Component {
- render() {
- return (
-
- "row">
- "col-xs-offset-2 col-xs-8">
- "page-header">
React Router Demo
-
-
- "row">
- "col-xs-2 col-xs-offset-2">
- "list-group">
-
"list-group-item" to="/about">About -
"list-group-item" to="/home">Home -
-
- "col-xs-6">
- "panel">
- "panel-body">
-
}> -
"/about" component={About}> -
"/home" component={Home}> -
-
-
-
-
-
- );
- }
- }
-
- export default Demo;
Home.jsx
- import React, {Component} from 'react';
-
- class Home extends Component {
- render() {
- return (
-
-
我是Home的内容
-
- );
- }
- }
-
- export default Home;
Loading.jsx
- import React, {Component} from 'react';
-
- class Loading extends Component {
- render() {
- return (
-
-
'gray', color: 'orange'}}>Loading
-
- );
- }
- }
-
- export default Loading;
App.js
- import React, {Component} from 'react';
- import Demo from "./components/Demo/Demo";
-
- class App extends Component {
- render() {
- return (
-
-
-
- );
- }
- }
-
- export default App;
index.js
- import React from 'react';
- import ReactDOM from 'react-dom/client';
- import App from './App';
- import {BrowserRouter} from "react-router-dom";
-
- const root = ReactDOM.createRoot(document.getElementById('root'));
-
- root.render(
-
-
-
- );
React Hook/Hooks是什么?
三个常用的Hook
State Hook
Demo.jsx
- import React, {Component} from 'react';
-
- // class Demo extends Component {
- // state = {count: 0}
- //
- // add = () => {
- // this.setState(state => ({count: state.count + 1}))
- // }
- //
- // render() {
- // return (
- //
- //
当前求和为{this.state.count}
- //
- //
- // );
- // }
- // }
-
- function Demo() {
- const [count, setCount] = React.useState(0)
- const [name, setName] = React.useState('tom')
-
- function add() {
- // setCount(count + 1)
- setCount((count) => {
- return count + 1
- })
- }
-
- function changeName() {
- // setName('jack')
- setName((name) => {
- return 'jack'
- })
- }
-
- return (
-
-
当前求和为{count}
-
我的名字是:{name}
-
-
-
- )
- }
-
- export default Demo;
Demo.jsx
- import React, {Component} from 'react';
- import ReactDOM from 'react-dom';
-
- // class Demo extends Component {
- // state = {count: 0}
- //
- // add = () => {
- // this.setState(state => ({count: state.count + 1}))
- // }
- //
- // unmount = () => {
- // ReactDOM.unmountComponentAtNode(document.getElementById('root'))
- // }
- //
- // componentDidMount() {
- // this.timer = setInterval(() => {
- // this.setState(state => ({count: state.count + 1}))
- // }, 1000)
- // }
- //
- // componentWillUnmount() {
- // clearInterval(this.timer)
- // }
- //
- // render() {
- // return (
- //
- //
当前求和为{this.state.count}
- //
- //
- //
- // );
- // }
- // }
-
- function Demo() {
- const [count, setCount] = React.useState(0)
-
- React.useEffect(() => {
- let timer = setInterval(() => {
- setCount(count => count + 1)
- }, 1000)
- return () => {
- clearInterval(timer)
- }
- }, [])
-
- function add() {
- setCount(count + 1)
- }
-
- function unmount() {
- ReactDOM.unmountComponentAtNode(document.getElementById('root'))
- }
-
- return (
-
-
当前求和为{count}
-
-
-
- )
- }
-
- export default Demo;
Demo.jsx
- import React, {Component} from 'react';
- import ReactDOM from 'react-dom';
-
- // class Demo extends Component {
- // state = {count: 0}
- //
- // myRef = React.createRef()
- //
- // add = () => {
- // this.setState(state => ({count: state.count + 1}))
- // }
- //
- // unmount = () => {
- // ReactDOM.unmountComponentAtNode(document.getElementById('root'))
- // }
- //
- // show = () => {
- // alert(this.myRef.current.value)
- // }
- //
- // componentDidMount() {
- // this.timer = setInterval(() => {
- // this.setState(state => ({count: state.count + 1}))
- // }, 1000)
- // }
- //
- // componentWillUnmount() {
- // clearInterval(this.timer)
- // }
- //
- // render() {
- // return (
- //
- // type="text" ref={this.myRef}/>
- //
当前求和为{this.state.count}
- //
- //
- //
- //
- // );
- // }
- // }
-
- function Demo() {
- const [count, setCount] = React.useState(0)
- const myRef = React.useRef()
-
- React.useEffect(() => {
- let timer = setInterval(() => {
- setCount(count => count + 1)
- }, 1000)
- return () => {
- clearInterval(timer)
- }
- }, [])
-
- function add() {
- setCount(count + 1)
- }
-
- function show() {
- alert(myRef.current.value)
- }
-
-
- function unmount() {
- ReactDOM.unmountComponentAtNode(document.getElementById('root'))
- }
-
- return (
-
- type="text" ref={myRef}/>
-
当前求和为{count}
-
-
-
-
- )
- }
-
- export default Demo;
作用
可以不用必须有一个真实的DOM根标签了
Demo.jsx
- import React, {Component, Fragment} from 'react';
-
- class Demo extends Component {
- render() {
- return (
-
- type="text"/>
- type="text"/>
-
- );
- }
- }
-
- export default Demo;
理解
一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信
使用
注意
Demo.jsx
- import React, {Component} from 'react';
- import './Demo.css'
-
- const MyContext = React.createContext()
- const {Provider, Consumer} = MyContext
- export default class A extends Component {
- state = {username: 'tom', age: 18}
-
- render() {
- const {username, age} = this.state
- return (
- "parent">
-
我是A组件
-
我的用户名是:{username}
-
-
-
-
- );
- }
- }
-
- class B extends Component {
- render() {
- return (
- "child">
-
我是B组件
-
-
- );
- }
- }
-
-
- // class C extends Component {
- // static contextType = MyContext
- //
- // render() {
- // const {username, age} = this.context
- // return (
- // "grand">
- //
我是C组件
- //
我从A组件接收到的用户名:{username},年龄是{age}
- //
- // );
- // }
- // }
-
- function C() {
- return (
- "grand">
-
我是C组件
-
我从A组件接收到的用户名:
-
- {
- value => {
- return `${value.username},年龄是${value.age}`
- }
- }
-
-
-
-
- )
- }
Demo.css
- .parent {
- width: 500px;
- background-color: orange;
- padding: 8px;
- }
-
- .child {
- width: 100%;
- background-color: skyblue;
- padding: 8px;
- }
-
- .grand {
- width: 100%;
- background-color: gray;
- padding: 8px;
- }
组件优化
原因
解决
办法一:Demo.jsx
- import React, {Component} from 'react';
- import './Demo.css'
-
- class Parent extends Component {
- state = {carName: "奔驰c36"}
-
- changeCar = () => {
- this.setState({})
- }
-
- shouldComponentUpdate(nextProps, nextState, nextContext) {
- console.log(this.props, this.state, 'Parent')
- console.log(nextProps, nextState, 'Parent')
- return !this.state.carName === nextState.carName
- }
-
- render() {
- console.log('Parent--render')
- const {carName} = this.state
- return (
- "parent">
-
我是Parent组件
- 我的车名字是:{carName}
-
-
-
- );
- }
- }
-
- class Child extends Component {
- shouldComponentUpdate(nextProps, nextState, nextContext) {
- console.log(this.props, this.state, 'Child')
- console.log(nextState, nextState, 'Child')
- return !this.props.carName === nextState.carName
- }
-
- render() {
- console.log('Child--render')
- return (
- "child">
-
我是Child组件
- 我接到的车是:{this.props.carName}
-
- );
- }
- }
-
- export default Parent;
Demo.css
- .parent {
- background-color: orange;
- padding: 10px;
- }
-
- .child {
- background-color: gray;
- margin-top: 30px;
- padding: 10px;
- }
办法二:Demo.jsx
- import React, {PureComponent} from 'react';
- import './Demo.css'
-
- class Parent extends PureComponent {
- state = {carName: "奔驰c36", stus: ['小张', '小李', '小王']}
-
- addStu = () => {
- // const {stus} = this.state
- // stus.unshift('小刘')
- // this.setState({stus: stus})
-
- const {stus} = this.state
- this.setState({stus: ['小刘', ...stus]})
- }
-
- changeCar = () => {
- // this.setState({carName: "迈巴赫"})
-
- const obj = this.state
- obj.carName = '迈巴赫'
- console.log(obj === this.state)
- this.setState(obj)
- }
-
- // shouldComponentUpdate(nextProps, nextState, nextContext) {
- // console.log(this.props, this.state, 'Parent')
- // console.log(nextProps, nextState, 'Parent')
- // return !this.state.carName === nextState.carName
- // }
-
- render() {
- console.log('Parent--render')
- const {carName} = this.state
- return (
- "parent">
-
我是Parent组件
- {this.state.stus}
- 我的车名字是:{carName}
-
-
-
"奥拓"> -
- );
- }
- }
-
- class Child extends PureComponent {
- // shouldComponentUpdate(nextProps, nextState, nextContext) {
- // console.log(this.props, this.state, 'Child')
- // console.log(nextState, nextState, 'Child')
- // return !this.props.carName === nextState.carName
- // }
-
- render() {
- console.log('Child--render')
- return (
- "child">
-
我是Child组件
- 我接到的车是:{this.props.carName}
-
- );
- }
- }
-
- export default Parent;
如何向组件内部动态传入带内容的结构(标签)?
children props
render props
Demo.jsx
- import React, {Component} from 'react';
- import './Demo.css'
-
- class Parent extends Component {
- render() {
- return (
- );
- }
- }
-
- class A extends Component {
- state = {name: 'tom'}
-
- render() {
- const {name} = this.state
- return (
- "a">
-
我是A组件
- {this.props.render(name)}
-
- )
- }
- }
-
-
- class B extends Component {
- render() {
- return (
- "b">
-
我是B组件,{this.props.name}
-
- )
- }
- }
-
- export default Parent;
Demo.css
- .parent {
- background-color: orange;
- padding: 10px;
- }
-
- .a {
- background-color: gray;
- margin-top: 30px;
- padding: 10px;
- }
-
- .b {
- background-color: skyblue;
- margin-top: 30px;
- padding: 10px;
- }
理解:
特点:
使用方式:
- // 生命周期函数,一旦后代组件报错,就会触发
- static getDerivedStateFromError(error) {
- console.log(error);
- // 在render之前触发
- // 返回新的state
- return {
- hasError: true,
- };
- }
-
- componentDidCatch(error, info) {
- // 统计页面的错误。发送请求发送到后台去
- console.log(error, info);
- }
Parent.jsx
- import React, {Component} from 'react';
- import Child from "./Child";
-
- class Parent extends Component {
- state = {
- hasError: ''
- }
-
- //当Parent的子组件出现报错时候,会触发getDerivedStateFromError调用,并携带错误信息
- static getDerivedStateFromError(error) {
- console.log(error)
- return {hasError: error}
- }
-
- componentDidCatch(error, errorInfo) {
- console.log('渲染组件时出错')
- }
-
- render() {
- return (
-
-
我是Parent组件
- {this.state.hasError ?
当前网络不稳定,稍后再试
: } -
- );
- }
- }
-
- export default Parent;
Child.jsx
- import React, {Component} from 'react';
-
- class Child extends Component {
- state = {
- // users: [
- // {id: '001', name: 'tom', age: 18},
- // {id: '002', name: 'jack', age: 19},
- // {id: '003', name: 'peiqi', age: 20},
- // ]
-
- users: 'abc'
- }
-
- render() {
- return (
-
-
我是Child组件
- {
- this.state.users.map((userObj) => {
- return
{userObj.name}-----{userObj.age}
- })
- }
-
- );
- }
- }
-
- export default Child;
组件间的关系:
几种通信方式:
- 1.props:
- (1).children props
- (2).render props
- 2.消息订阅-发布:
- pubs-sub、event等等
- 3.集中式管理:
- redux、dva等等
- 4.conText:
- 生产者-消费者模式
比较好的搭配方式: