React 学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
React 基础
 
react.development.js 核心js
react-dom.development.js dom渲染js文件 有先后顺序
 
使用...展开语法:
    let arr = [1,2,3,4];
    console.log(...arr) // 1,2,3,4
内联样式写法:
    <input type="text" name="username" style={{fontSize:'12px'}}>
类式组件:
    class MyComponent extens React.Component{
        1. render() 方法核心
        render(){
            return(
                // render 只能返回单节点(一个div包裹)
            )
        }
    }
初始化对象状态state
    1. 可以在实例对象创建时:
        constructor() {this.state = {a:1}}
    2. 也可以直接在类中定义:
        class Persion {
            state = {a: 1}
        }
    3. 如果需要修改state中的值, 使用 this.setState({a:2})
 
react对标签属性的限制
    需要引入prop-types.js
    类外面的写法
    1.react 组件类型限制:
        类.propTypes={
            name: PropTypes.string.isRequire,   限制name为必填string类型
            age: PropTypes.number               限制age为数字类型
            say: PropTypes.func                 限制say为函数类型
        }
    2.react 指定默认属性
        类.defaultProps = {
            sex: '男',  设置默认sex为男
            age: 17
        }
    3.类里面的写法 static, 对象静态属性
        static propTypes={
            name: PropTypes.string.isRequire,   限制name为必填string类型
            age: PropTypes.number               限制age为数字类型
            say: PropTypes.func                 限制say为函数类型
        }
 
函数式组件:
    1. 所有的参数都会在props中
    2. 函数式组件中 没有state   , 没有refs
    function MyComponent(props){
        return (
            <h1>test</h1>
        )
    }
总结: 组件传参数 可以使用...语法 , 解构赋值 const {a,b} = this.props //
    解构赋值连续写法:
        const {target: {value}} = this.event // value 就是target.value 写法
    render() : 方法会被调用1+n次, 初始化渲染和组件更新才会调用
组件生命周期 (旧版 16):
    1.卸载组件:
        ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    2. 组件挂载完毕
        componentDidMount(){ }
    3. 组件将要卸载执行
        componentWillUnmount(){}
    4. 组件将要挂载
        componentWillMount(){}
    5. 执行setState 会调用这个钩子决策,返回true通过,false 更新取消,默认一直为真
        shouldComponentUpdate(){}
    6. 组件将要更新
        componentWillUpdate(){}
    7. 组件更新完毕 (可以接收3个参数, 第三个就是快照值)
        componentDidUpdate(){}
    8. 强制更新状态, 当执行this.forceUpdate()   只会执行componentWillUpdate() 钩子
 
    9. 当父组件更新时,子组件才会执行(第一次渲染不会执行哦)
        componentWillReceiveProps(props){}
组件生命周期 (新版):
    1.这个3个钩子如果使用,前面需要加上 UNSAFE_ 前缀, 在未来异步渲染中可能会出bug
        componentWillMount
        componentWillReceiverProps
        componentWillUpdate
    2. 新增加两个钩子:
        无用: getDerivedStateFormProps(){} // new props setState forceUpdate 执行
        getSnapshotBeforeUpdate(){} // 该方法返回快照值,交给 componentDidUpdate 钩子
 
    总结:
    常用的 也就是 constructor 实例化  render渲染
    componentDidMount挂载完毕  componentWillUnmount
 
事件处理:
    js中: onclick
    react: onClick={this.method}, onBlur={},onChange={}
    react 调用method方法会传递事件源(event)=> event.target.value 即可获取当前input值
表单提交:
    表单提交事件 - 受控组件(通过ref获取元素值):
            this.refs.username.value
            this.refs.password.value
        handleSubmit = event=>{
            event.preventDefault() // 阻止默认表单提交
            // 不适用表单提交发送请求
        }
        <form onSubmit={this.handleSubmit}>
            <input ref={e=>this.username=e} type="text" name="username">
            <input ref={e=>this.password=e} type="text" name="password">
            <button>提交</button>
        </form>
    非受控组件 - 通过onChange 动态获取用户输入,存入state:
        changeUsername = e => {
            this.setState({username: e.target.value})
        }
        <input  name="username" onchange={this.chanageUsername}>
函数柯里化:
    1.在使用非受控组件时,会存在一个问题,就是我有很多个input,会出现很多个对应的方法
    2.函数柯里化解决这个问题:
        state = {
            username: ''
        }
        saveFormDate = name => {
            return e => {
                // key : value 方式存入state
                this.setState({[name]: e.target.value})
            }
        }
        <input type="text" onChange={this.saveFormDate('username')}> // 调用函数并传递一个name标识
    3.不用科里化实现:
        state = {
            username: ''
        }
        saveFormDate = (name,e) => {
            this.setState({[name]: e.target.value})
        }
        <input type="text" onChange={(e)=>{this.saveFormDate('username',e)}}> // onChange react 会帮你调用
 
refs获取元素(2,3 都可以 没有什么影响):
    1.字符串方式(将要废弃):
        声明: 类似vue: <input ref="input1">  
        使用: this.refs.input1.value 就可以获取input的值
    2.回调方式-内联方式 (render 更新会渲染两次):
        render(){
            return (<div>ref={(e)=>{this.input1=e}}</div>)
            简写方式
            return (<div>ref={e=>this.input1=e}</div>)
        }
    3.优化回调方式,调用类方法:
        // 在类中定义方法
        saveInput=(e)=>{
            this.input1 = e;
        }
        render(){
            return (<div>ref={this.saveInput}</div>)
            简写方式
            return (<div>ref={e=>this.input1=e}</div>)
        }
    4.createRef 最新方式:  
        创建: myRef = React.createRef() // 只能存放一个元素
        使用: <input ref={myRef}>
        获取input值: this.myRef.current.value
 
子组件如何给父组件传值:
    1. 函数回调的方式
    class A extends React.Component{
        callback_date = childDate => {
            console.log(childDate)
        }
 
        render(){
            return (
                // 当header 中调用callback_parent 会调用父组件方法
                <Header callback_parent={this.callback_date}/>
            )
        }
    }
数组方法:
    forEach() 循环,遍历
    const arr2 = arr.map((v,i,arr)=>{v}) 遍历
    filter() 过滤使用
    reduce() 统计使用
react 配置代理:
    setupProxy.js 新建
    const proxy = require('http-proxy-middleware') 使用这个模块
react 脚手架使用:
网络请求:
    axios 
父子组件通信:
    pubsubjs.js 
    1. 谁用数据谁就订阅消息(先订阅在发布)
路由组件和一般组件有什么不同:
    1. 写法不同:
        <About />
        <Route path="/about" component={About}></Route>
    2. 存位置不同:
        pages/   components/
    3. 接收参数不同:
    路由组件接收到的props:
        history:
            go
            goBack
            goForward
            push
            replace
        location:
            pathname: "/about"
            search: ''
            state:
        match:
            parms: {}
            path: '/about'
            url: '/about'
react 如何使用路由:
    1. 引入 react-router-dom.js
    2. 引入组件库  import {Link, BrowserRouter,Route} from 'router-router-dom'
        路由类型:  全局唯一必须把Link 和 Route包起来 应该放在最外侧
            <BrowserRouter>
                <App/>
            </BrowserRouter>
    路由分类: BrowserRouter: 非锚点路由 /a/ba/c, HashRouter锚点路由  /home#/aaa #号后面不会发送到服务端
        Route 注册路由(坐映射关联)
        Link 路由链接实现组件切换, 必须在外侧包裹哪一种路由类型:
        <BrowserRouter>
            <Link to="/about">点击我去about组件</Link>
            <Link to="/home">点击我去home组件</Link>
    3.注册路由(link 对应的) exact={true} 精准匹配(默认是模糊匹配路由,不能随便开启,开启会导致2级路由失效)
            <Route path="/about" exact={true} component={About}></Route>
            <Route path="/home" component={Home}></Route>
        </BrowserRouter>
    4. 提高路由匹配效率:
        <Switch/> 效率比较高, 匹配到路由会直接返回,不会继续匹配
    5. 如何实现路由点击高亮效果:
        使用Link升级版:
            <NavLink to="/about" activeClassName={xxx}>点击我去about组件</NavLink>
            ***标签体内容是一个特殊的属性. this.props.children 可以获取标签体内容
            4.1 点击默认追加action class, 也可以使用actionClassName 指定样式
    6. 默认选中:
        <Redirect to='/about'/> 
        1. 一般写在最下方,没有匹配到路由的情况下跳转到redirect指定的路由
      
路由组件传值几种方式:
    1.第一种params: 直接在路由后面拼接:
        <Link to="/about/1">点击我去about组件</Link>
        声明接收一个变量id (可以拼接多个/:id/:title),About组件props中查看 , this.props.match.params
        <Route path="/about/:id" component={About}></Route>
    2. 第二种search:
        <Link to="/about/?id=1&title=aaa">点击我去about组件</Link>
        无需声明接收,直接在About 中props接收, this.props.location.search  // ?id=1&title=aaa 需要自己处理
        ***可以借助querystring 库处理
        <Route path="/about" component={About}></Route>
    3. ***state 方式, 不是组件的state,不能按照之前的方式,, 地址栏不会显示参数
        <Link to={{pathname:'/about', state:{id:1,title:'xxx'}}}>点击我去about组件</Link>
        无需声明接收,直接在About 中props接收, this.props.location.state  // 无需处理,比较爽
编程式导航(只有路由组件才有history):
    通过点击事件函数跳转,this.porps.history.push/this.porps.history.replace
        this.porps.history.push('/about')
        this.porps.history.replace('/about')  跳转不留痕迹
        this.porps.history.goBack()
        this.porps.history.goForward()
使用withRouter ,让一般组件有路由组件的API,解决一般组件使用history问题
    import {withRouter} from 'react-router-dom'
    class Header extends Component{}
    export default withRouter(Header)
 
        

  

posted @   qukaige  阅读(52)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2019-05-27 数据结构学习(一) Java中的动态数组实现
2018-05-27 paramiko 实现远程切换root
点击右上角即可分享
微信分享提示