React入门(初步)

创建

脚手架搭建

npx create-react-app 项目名

创建组件

导入组件

import React from "react"
import ReactDOM from 'react-dom'

render导入视图

1.使用箭头函数
  • 基本

    
    //方法
    const creactApp =(props)=>{
        return (
            <div>
                {/* 只要在jsx中里擦呼入js的代码,就加一层花括号,注释也是js,所以这里的注释加了一层花括号 */}
                <h1>Welcome {props.title}!!!!</h1>
                <p>youxiu</p>
            </div>
        )
    }
    
    //实现
    const app = creactApp({
        title:"React 16.8",
    })x
    ReactDOM.render(
        app,
        document.querySelector("#root")
    )
    
  • 化简

    const App =(props)=>{
        return (
            <div>
                {/* 只要在jsx中里擦呼入js的代码,就加一层花括号,注释也是js,所以这里的注释加了一层花括号 */}
                <h1>Welcome {props.title}!!!!</h1>
                <p>youxiu</p>
            </div>
        )
    }
    
    ReactDOM.render(
        <App title="1901"/>,
        document.querySelector("#root")
    )
    
2.使用类组件
  • 方法

    const Header = () => <h1>类组件!!!</h1>
    class App extends React.Component{
        render () {
            console.log(this.props)
            return (
                <div>
                	<Header />
                    <h1>类组件</h1>
            <p>{this.props.title},{this.props.x}</p>
                </div>
            )
        }
    }
    
     render(x
         <App title="类组件继承" x="abc"/>,
         document.querySelector('#root')
     )
    
  • render原理

    const app = new App({
        title:'类组件继承'
    }).render()
    render(
        app,
        document.querySelector('#root')
    )
    render(
        <App title="类组件继承" x="abc"/>,
        document.querySelector('#root')
    )
    

使用样式

const Title = styled.h1`color:#F00`

class App extends Component{
    render(){
        const style = {color:"#f00"}
        return(
            <div>
                {/* <h1 style={{color:"red"}}>元素中的样式</h1> */}
                <Title >元素中的样式</Title>
                <ol>
                    <li style = {style}>使用style的link样式创建</li>
                    <li className="has-text-red">使class的方式,但是在react里class要写成className</li>
                    <li className={classNames('a',{'b':true,"c":false})}>
                        要动态添加不同的classname就可以使用第三方的包叫className,比如这个里标签上只有啊,b没有c
                        </li>
                </ol>
                <li >style-components</li>
            </div>
        )
    }
}

开始搭建平台

  1. 启动器

    index.js

    import React from 'react'
    import {render} from 'react-dom'
    import App from './App'
    
    render(
        <App />,
        document.querySelector("#root")
    )
    
  2. 框架

    rcc类模式,rfc函数模式

    app.js(以类模式为例)

    import React, { Component,Fragment } from 'react'
    import { TodoHeader, TodoInput, TodoList } from './components'//各种组件
    
    export default class App extends Component {
        render() {
            return (
                <Fragment>
                    app
                    <TodoHeader />
                    <TodoInput />
                    <TodoList />
                </Fragment>
            )
        }
    }
    

    因为导出时只能返回一个根标签所以要加div但是要是显示时想去掉:

    1.导入react的Fragment写成上述方式

    2.直接写成<></>

变量

导入变量

app.js

 <TodoHeader desc="今日事,今日毕">    
    <i>代办事项</i>{/*props.children变量*/}
</TodoHeader>

组件

  • 函数形式
export default function TodoHeader(props) {
    console.log(props)
    return (
        <div>
            <h1>
                {props.children}
            </h1>
            <h3>{props.desc}</h3>
        </div>
    )
}
  • 类模式

    export default class TodoList extends Component {
        render() {
            return (
                <div>
                    TodoList
                    <TodoIitem />
                </div>
            )
        }
    
}
 ```
  • 外部组件(类)

    export default class App extends Component {
        constructor(){
            super()
            this.state = {
                desc: "今日事,今日毕",
                title:"sjkfa"
            }
        }
        render() {
            return (
                <Fragment>
                    <TodoHeader desc={this.state.desc}></TodoHeader>
                </Fragment>
            )
        }
    }
    

    注意:

    1.数字变量要用于运算要写成{2}

管理变量

install

npm install --save prop-types

函数模式

export default function TodoHeader(props) {...}

//组件的样式
TodoHeader.propTypes={
    desc:propTypes.string.isRequired,
    x:propTypes.number,
    y:propTypes.number,
    children:propTypes.object
}

//组件的默认值
TodoHeader.defaultProps = {
    desc:"如果还有明天"
}

类模式

export default class TodoInput extends Component {
    //组件的样式
    static propTypes = {
        btnText: PropTypes.string
    }

    //组件的默认值(变量名不可变)
    static defaultProps = {
        btnText: "添加ADD"
    }
    render() {...}
}

管理类的方式

export default class TodoList extends Component {
    static propTypes = {
        todos:PropTypes.arrayOf(PropTypes.shape({
            id:PropTypes.number.isRequired,
            title: PropTypes.string.isRequired
        }))   
    }
}
字符转html
<div dangerouslySetInnerHTML={{__html: this.state.article}}></div>
循环
 this.state.todos.map(todo =>{
 return <div key={todo.id}>{todo.title}</div>
 })

方法

使用onClick方法来监听事件的发生

在类中编译方法

使用this.state.isLiked != this.state.isLiked可以改值但是界面不会重新渲染

应该使用this.setState方法来渲染界面

界面:

export default class Like extends Component {
    constructor(){
        super()
        this.state = {
            isliked: false
        }
    }
    handleLikedClick = ()=>{
        //使用这种方式可以改值但是界面不会重新渲染
        //this.state.isLiked != this.state.isLiked
        //要修改数据,就使用setState方法,setState有两个参数
        //第一个参数又有两种:
        //对象形式:
        // this.setState({
        //     isliked: !this.state.isliked
        // })
        //第二是方法,
        this.setState((prebState,props)=>{
            console.log("like的prebState",prebState,props)
            console.log("setStaate内部的this.state.isliked",this.state.isliked)
            return {
                isLiked:! prebState.isLiked//改值是在返回时发生的
            }
        },()=>{
            //由于setState是一个异步方法,如果想要最新的state,应该在这个回调里来获取
            console.log(this.state.isLiked)
        })
        console.log("setStaate外部的this.state.isliked",this.state.isliked)
        
    }
    render() {
        return (
            <div>
                <span onClick={this.handleLikedClick}>
                {
                    this.state.isliked ?'取消❤️':'喜欢 🖤'
                }
                </span>
            </div>
        )
    }
}

输入框改值

bind只有值发生变化时才会用

handleInputChange = (e)=>{
        // console.log(e.currentTarget.value)
        this.setState({
            inputValue:e.currentTarget.value
        })
    }

为了让函数只渲染一次就把函数的赋值在构造中

    constructor(){
        super()
        this.state={
            inputValue:"ert"
        }
        this.handleAddClickCopy = this.handleAddClick.bind(this)
    }
     handleAddClick() {
        console.log(this.state)
    }
render() {
        return (
            <div>
                <input 
                type="text" 
                value={this.state.inputValue}
                onChange={this.handleInputChange}/>
                <button onClick={this.handleAddClick}>{this.props.btnText}</button>
            </div>
        )
    }
优化

修改前:

<button onClick={()=>{
        console.log(this.state)
    }}>{this.props.btnText}</button>

因为这样做会渲染方法所以我们将函数的定义放在外面

  • 渲染时将方法修改

     <button onClick={()=>{this.handleAddClick(1234)}}>{this.props.btnText}</button>
    

    渲染时将方法执行

    <button onClick={this.handleAddClick(1234)}>{this.props.btnText}</button>
    

    为了方便(综合上面的优势)得

    <button onClick={this.handleAddClick.bind(this,1234)}>{this.props.btnText}</button>
    
  • 全局模式的定义

    addTodo = (todoTitle)=>{
            console.log(todoTitle)
        }
        render() {
            return (
                <Fragment>
                    <TodoInput 
                    addTodo={this.addTodo}/>
                    <TodoList todos={this.state.todos}/>
                </Fragment>
            )
        }
    

    TodoInput组件:

    handleAddClick = ()=>{
            this.props.addTodo(this.state.inputValue)
        }
     render() {
            return (
                <div>
                    <input 
                    type="text" 
                    value={this.state.inputValue}
                    onChange={this.handleInputChange}/>
                    <button onClick={this.handleAddClick}>{this.props.btnText}</button>
                </div>
            )
        }
    

修改值(界面更新使用)

同样我们要使用setState方法就可以进行渲染(全局的!!)

addTodo = (todoTitle) => {
        console.log(todoTitle)
        // this.setState({
        //     返回了长度 todos =3了
        //     todos:this.state.todos.push({
        //         id:Math.random(),
        //         title:todoTitle,

        //         isCompleted:false
        //     })

        // })

        // //正确
        // this.setState({
        //     todos: this.state.todos.concat({
        //         id: Math.random(),
        //         title: todoTitle,

        //         isCompleted: false
        //     })
        // })

        // const newTodos = this.state.todos.slice()
        const newTodos = [...this.state.todos]
        newTodos.push({
            id: Math.random(),
            title: todoTitle,
            isCompleted: false
        })
        this.setState({
            todos:newTodos
        })
    }

多级方法的优化

app.js

 <TodoList todos={this.state.todos}
                onCompeletedChange={this.onCompeletedChange} />
 <TodoIitem
	onCompeletedChange={this.props.onCompeletedChange}
	key={todo.id}
	{...todo} 
     />
const noop=() =>{}
export default class TodoItem extends Component {
    handleCheckboxChange = ()=>{
        console.log("change")
        //如果最后没有传过来可以继续运行
        // this.props.onCompeletedChange&&this.props.onCompeletedChange(this.props.id)
        const {
            onCompeletedChange = noop,
            id
        }=this.props
        onCompeletedChange(id)
    }
    render() {
        // console.log("TodoItem",this.props)
        const {
            isCompleted,
            title
        } = this.props
        return (
            <li>
                <input type="checkbox" 
                checked={this.props.isCompleted}
                onChange={this.handleCheckboxChange}
                /><span>{this.props.title}:{this.props.isCompleted?"已完成":"未完成"}</span>
            </li>
        )
    }
}

针对多次渲染的问题

1.使用react的PureComponent类代替Component

export default class TodoItem extends PureComponent {
    constructor (){
        super()
        this.state = {}
    }
    
    handleCheckboxChange = ()=>{
        const {
            onCompeletedChange = noop,
            id
        }=this.props
        onCompeletedChange(id)
    }

    render() {
        console.log(`TodoItem ${this.props.title}render`)
        // console.log("TodoItem",this.props)
        const {
            isCompleted,
            title
        } = this.props
        return (
            <li>
                <input type="checkbox" 
                checked={this.props.isCompleted}
                onChange={this.handleCheckboxChange}
                /><span>{this.props.title}:{this.props.isCompleted?"已完成":"未完成"}</span>
            </li>
        )
    }
}

跳转

react里面通过ref来获取组件或者dom元素,要使用ref之前必须先调用React.createRef方法来创建一个ref

生命周期

生命周期图

UNSAFE_componentWillMount

 static getDerivedStateFromProps(){
     return {}
 }
//上面那个函数有了这个了,所以下面这个不能存在
//这个函数在更新前启动
 /*
 UNSAFE_componentWillMount(){
     console.log('UNSAFE_componentWillMount')
 }*/

更新

  • 老版本的坑:constructor里面通过props来初始化一个state,在props修改之后,这个state不会再次更新
 constructor (props){
     super()
     this.state = {
         competedText:nextProps.isCompleted?'完成':'未完成'
     }
 }

那么就需要借助于UNSAFE_componentWillReceiveProps来做一次修正

UNSAFE_componentWillReceiveProps(nextProps) {
     this.setState({
         competedText:nextProps.isCompleted?'完成':'未完成'
     })
}
  • 新方法
    constructor(){
        super()
        this.state={
            competedText:''
        }
    }

    static getDerivedStateFromProps (props){
        return{
            competedText:props.isCompleted?'完成':'未完成'
        }
    }

网络编程(axios)

npm install axios -S

Hook

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

import React, { useState } from 'react';

function Example() {
  // 声明一个新的叫做 “count” 的 state 变量
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

监视更新

useEffect((=>{
           document.title="标题"
}))

例:

//两个常见的api就是 useState,useEffect,需要先引入
import React, { useState,useEffect } from 'react'
import {render} from 'react-dom'


const Counter = () =>{  

    // useState是一个方法,这个方法的参数就是默认值,结果是一个数组,数组的第一个就是state,第二个就是相当于setSate
    //解构出来两个数组中的两个值
    const [count, setcount] = useState(0)
    //userEffer就是一个回调,不管是组件的挂载还是更新,都会触发这个回调方法
    useEffect(()=>{
        console.log("渲染了")
        document.title = `当前数量为${count}`
    })
    return (
        <div>
            <p>当前数量为{count}</p>
            <button onClick={()=>{setcount(count-1)}}>-</button>
            {/*这里的setCount就是useState所生成的方法。注意和setState的参数不同,这里的参数是一个新值即可*/}
            <span>{count}</span>
            {/* 这里就是useState创建的值 */}
            <button onClick={()=>{setcount(count+1)}}>+</button>
        </div>
    )
}

render(
    <Counter/>,
    document.querySelector("#root")
)

Context

//createContext是react提供的一个用于跨组件创制的方法
import React, { Component, createContext } from 'react'
import { render } from "react-dom"

console.log(createContext())

//createContext这个方法的结果是一个对象,里面有Provider和Consumer
//Provider用于提供状态
//Consumer用于接收状态
const {
    Provider,
    Consumer: CounterConsumer//结构出来重新赋值给一个CounterConsumer的组件
} = createContext()


//封装一个基本的Provider,因额外i之间使用Provider,不方便管理状态
class CounterProvier extends Component {

    constructor() {
        super()
        //这里的组
        this.state = {
            count: 100
        }
    }
    incrementCount = () => {
        this.setState({
            count: this.state.count + 1
        })
    }
    decrementCount = () => {
        this.setState({
            count: this.state.count - 1
        })
    }
    render() {
        return (
            //使用Provider这个组件,它必须要有一个value值,这个value里可以传递任何的数据,一般还是传送一个对象比较合理
            <Provider value={{
                count: this.state.count,
                onDecrementCount: this.decrementCount,
                onIncrementCount: this.incrementCount
            }}>
                {this.props.children}
            </Provider>

        )
    }
}

//定义一个Counter组件
class Counter extends Component {
    // state
    render() {
        return (
            //使用Count了Cousumer来接收count
            <CounterConsumer>
                {
                    //注意注意!!!Coumer的children必须是一个方法,这个方法有一个参数,这个参数就是Provider的value
                    ({ count }) => {
                        //
                        // console.log(count)
                        return <span>{count}</span>
                    }
                }
            </CounterConsumer>
        )
    }
}

class CountBtn extends Component {

    render() {

        return (
            <CounterConsumer>
                {
                    ({ onDecrementCount, onIncrementCount }) => {
                        const handler = this.props.type === 'increment' ? onIncrementCount : onDecrementCount
                        return <button onClick={handler}>{this.props.children}</button>
                    }
                }
            </CounterConsumer>
        )
    }
}

class App extends Component {
    render() {
        return (
            <>
                <CountBtn type="decrement">-</CountBtn>
                <Counter />
                <CountBtn type="increment">+</CountBtn>
            </>
        )
    }
}

render(
    <CounterProvier>
        <App />
    </CounterProvier>,
    document.querySelector('#root')
)

HOC及CRA

高阶函数

高阶组件

react-lesson-03

通过使用参数是函数的方法来装饰组件

  • 整体表示

    const testHOc = (WrappedComponent) =>{
        return class HoCComponent extends Component{
            render() {
                return (
                    <>
                        <WrappedComponent/>
                        <div>这是高阶组件里的信息</div>
                    </>
                )
            }
        }
    }
    
    class App extends Component {
        render() {
            return (
                <div>
                    <Button type="primary">dian</Button>
                    App
                </div>
            )
        }
    }
    
    
    export default testHOc(App)
    
  • 分开表示

index.js

import React from 'react'
import {render} from 'react-dom'
import App from './App'

render(
    <App />,
    document.querySelector('#root')
)

App.js

import React,{Component} from 'react'
import withCopyright from './withCopyright'
import Another from './Another'

class App extends Component {
    render(){
        return (
            <div>
                App
                <Another name="组件"/>
            </div>
        )
    }
}

export default App

withCopyright.js

import React, { Component } from 'react'

const withCopyright = (YourComponent) =>{
    return class withCopyright extends Component {
        render () {
            console.log(this)
            return (
                <p>
                    <YourComponent {...this.props}/>
                    这是高阶内容
                    <div>&copy;2019 &emsp; 前锋教育</div>
                <p/>
            )
        }
    }
}

export default withCopyright

Another.js

import React, { Component } from 'react'
import withCopyright from './withCopyright'

class Another extends Component {
    render() {
        return (
            <div>
              AnOther {this.props.name}
              
            </div>
        )
    }
}

export default withCopyright(Another)

装饰器模式

Another.js变成了这样(写成这样)

import React, { Component } from 'react'
import withCopyright from './withCopyright'

@withCopyright
class Another extends Component {
    render() {
        return (
            <div>
              AnOther {this.props.name}
              
            </div>
        )
    }
}

export default Another
方法

npm install react-app-rewired --save-dev

然后将package.json的build,test,start运行编码的react-scripts改为react-app-rewired

npm install customize-cra --save-dev

npm i @babel/plugin-proposal-decorators -D

让cra支持@装饰器写法:

  1. 不管你是要配置什么,我们最好的方式是使用react-app-rewired这个包来对cra创建的项目进行轻微的配置调整

  2. 安装好之后,在package.json里把scripts里的react-scripts替换成reactapp-rewired

  3. 在根目录下创建一个config.overrides.js

    const { override,addDecoratorsLegacy } = require('customize-cra')
    
    module.exports = (config) => {
        //如果没有customize-cra在这里可以对config配置
        return config
    }
    
    
  4. 当然如果想要配置更方便可以安装customize-cra然后config.overrides

    const { override,addDecoratorsLegacy } = require('customize-cra')
    
    module.exports = override(
        addDecoratorsLegacy()
    )
    

状态管理:

**https://git.dev.tencent.com/leochow/react-tuts-1901.git

Redux

HTMl样式

**

```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div>
        <button onclick="store.dispatch({type:'JIAN',n:2})">-</button>
        <span id="countDisplay"></span>
        <button onclick="store.dispatch({type:'JIA',n:2})">+</button>
    </div>
    <script>
        const countDisplay = document.querySelector('#countDisplay')
        const countState = {
            count: 10
        }
        // const renderCount = (state)=>{
        //     countDisplay.innerHTML = state.count
        // }
        // renderCount(countState)


        const changeState = (state, action) => {
            if(!state) {
                return countState
            }
            switch (action.type) {
                case 'JIA':
                    return {
                        ...state,
                        count:state.count+action.n
                    }
                case 'JIAN':
                return {
                        ...state,
                        count:state.count-action.n
                    }
                default: 
                    return state
            }
        }

        const dispatch = (action) => {
            changeState(action)
            renderCount(countState)
        }

        const createStore = (render) => {
            let state=null
            const getState = () => state
            const listeners = []
            const subsribe = (listener) => listeners.push(listener)
            const dispatch = (action) => {
                state = changeState(state,action)
                listeners.forEach(listener => listener())
            }
            dispatch({})
            return {
                getState,
                dispatch,
                subsribe
            }
        }

        const store = createStore( changeState)

        const renderCount = () => {
            countDisplay.innerHTML = store.getState().count
        }

        renderCount()

        store.subsribe(renderCount)
    </script>
</body>

</html>

手写

lesson-04

npm i redux -S

1.编写一个store.js文件

import { createStore } from 'redux'

import rootReducer from './reducers'

export default createStore(rootReducer)

react-redux

lesson-05

npm install --save react-redux

dispatch()运行一次redux方法

                <tbody>
                    {
                        // console.log(id)
                        this.props.cartList.map(item => {
                            return (
                                <tr key={item.id}>
                                    <td>{item.id}</td>
                                    <td>{item.title}</td>
                                    <td>{item.price}</td>
                                    <td>
                                        <button onClick={
                                            () => {
                                                this.props.reduce(item.id)
                                                
                                            }
                                        }>-</button>
                                        <span>{item.amount}</span>
                                        <button onClick={
                                            () => {
                                                this.props.add(item.id)
                                            }
                                        }>+</button>
                                    </td>
                                </tr>
                            )
                        })
                    }
                </tbody>


// mapStateToProps, 这里的state实际上就store.getState()的值
const mapState = (state) => {
    // 这里return了什么,在组件里就可以通过this.props来获取
    return {
      cartList: state.cart
    }
  }

const mapDispatchToProps = dispatch =>{
    return{
        add:(id)=> dispatch(increment(id)),
        reduce: (id) =>dispatch(decrement(id))
    }
}
 export default connect(mapState,mapDispatchToProps)(CartList)

目前编写方法

<button onClick={this.props.decrement.bind(this,item.id)}>-</button>

const mapDispatchToProps = dispatch =>{
    return{
        add:(id)=> dispatch(increment(id)),
        reduce: (id) =>dispatch(decrement(id))
    }
}

export default connect(mapState,{increment,decrement,decrementAsyn})(CartList)

1.创建reducers

2.合并reducers

3.createStore

4.Provider store = {store}

5.connect (mapStateToProps,{。。actionCon})

React-Router

react-lesson-08

npm install react-router-dom -S

渲染方式

​ 在App.js文件中加入router-dom组件的HashRouterRoute

import React from 'react'
import { render } from 'react-dom'

// import { BrowserRouter as Router,Route } from 'react-router-dom'
import {HashRouter as Router,Route} from 'react-router-dom'
import App from './App'

render(
    <Router >
        <Route component={App}/>
        
    </Router>,
    document.querySelector("#root")
)

组件

  • route路由器组件

    • component= {组件}
    • path= ‘\path’
  • Link路由器跳转

  • to跳转路径

  • HashLink功能比Link多一个Classname属性

  • Redirect从一个路径转换到另一个路径

    • from原始路径
    • to跳转路径
  • Switch选择路径,使得渲染成功后不再继续搜素下一个路由

    <Switch>
        <Route component={Home} path="/home"></Route>
        <Route component={Artical} path="/artical" exact/>
        <Route component={ArticalDetail} path="/artical/:id"/>
        <Route component={Users} path="/user" />
        <Redirect to="/home" from="/"/>
    </Switch>
    

    exact用于继续运行

附加:

render方式组件

   <Route path="/home" render={(routerProps)=>{           
        console.log(routerProps)
        return<Home {...routerProps} x={1}/>
    }}></Route>

router的页面跳转(的跳转方式)只有使用router组件时才可以使用router的api

  goHome = () => {
        // this.props.history.push('/home')
        this.props.history.push({
            pathname: '/home',
            state: {
                id: this.props.match.params.id
            }
        })
    }

在非router组件的router中需要添加RouterwirhRouter组件

import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'

class A exend Component{}

export default withRouter(A)

传参方式:

  1. query

  2. 使用state隐式传参

    <Link to={{
            pathname:"/artical/2",
                state:{
                    from:'qed'//隐式传参
                }
        }}>文章二</Link>
    
  3. 动态路由/path/:param=>params

    <Link to="/artical/1/hhh"/>
    {/*route.path="//artical/:id/:from" */}
    

Ant Design(软件的使用)

软件的使用(电脑)

手机端软件

npm i antd -S

高级配置

npm i react-app-rewired customize-cra -D

npm i babel-plugin-import -D

配置config-overrides.js文件在根目录

const { override, fixBabelImports } = require('customize-cra');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',//手机端是antd-mobile
        libraryDirectory: 'es',
        style: 'css',
    }),
);

设置自定义

npm i less less-loader -D

const { override, fixBabelImports ,addLessLoader} = require('customize-cra');

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd',//手机端是antd-mobile
        libraryDirectory: 'es',
        style: true,
    }),
    addLessLoader({
        javascriptEnabled: true,
        modifyVars: { 
            '@primary-color': '#F00' //设置颜色
        }
    })
);

国际化

import React from 'react';
import {render} from 'react-dom'
import App from './App';
import zhCN from 'antd/lib/locale-provider/zh_CN'
import {LocaleProvider} from 'antd'

render(
<LocaleProvider locale={zhCN} >
    <App/>
</LocaleProvider>,
 document.getElementById('root'));

项目

标准的注释语法

/**
 * @file config-overrides.js
 * @author ChuyongWei
 * 基于customize-cra和react-app-rewired的指定化配置文件
 */

懒加载

npm i react-loadable -S

原理:
// 这个文件只是用于解释react-loadable原理用。当然可以无缝切换
import React, { Component } from 'react'

const Loadable = ({
  loader,
  loading: Loading
}) => {
  return class LoadableComponent extends Component {
    state = {
      LoadedComponent: null
    }
    componentDidMount() {
      // import('./Dashboard')
      loader()
        .then(resp => {
          this.setState({
            LoadedComponent: resp.default
          })
        })
    }
    render() {
      const {
        LoadedComponent
      } = this.state
      return (
        LoadedComponent
        ?
        <LoadedComponent />
        :
        <Loading />
      )
    }
  }  
}
export default Loadable
使用

类似于导出

import Loadable from 'react-loadable'
import { Loading } from '../components'//等待时的页面

const ArticleEdit = Loadable({
    loader: () => import('./Article/Edit'),//引用的页面
    loading: Loading
})
export {Dashboard}

如果遇到有些组件导不进去就从替他地方导

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值