知识点扩展
1 模块导入简写, 3种方式可实现一样的效果
1 import React, {
Component} from 'react'
2 import React from 'react' / import {
Component} from 'react'
3 import React from 'react' / const Component = React.Component
2 状态提升干的事
1 当兄弟组件之间需要对某些数据进行共享时
2 把需要被共享的数据, 定义在共同的父组件中, 通过组件通信使用
3 React规范: 一切外部数据都要通过 props传递进来
JSX
1 理解
1 Jsx 是 JS的一种语法扩展 (语法糖)
2 非必须, React推荐的语法格式
3 书写的代码, 优雅, 便于维护
4 Jsx 可防注入攻击 (XSS)
5 Jsx 中可以直接写 HTML元素
6 Jsx 中属性 (className 代替 class) (htmlFor 代替 for) (tabIndex 代替 tabindex)
2 使用
1 核心: React 中的变量都要在 {}中书写
2 注释: {/* 注释内容 */}
定义组件的俩种方式
1 class 组件类
----------------------------------------------------------------
import React, from 'react'
class P1 extends React.Component{
constructor() {
super()
this.state = {
msg: '爱情是相互欣赏'
}
}
render(h) {
return (<div> <h3> {
this.state.msg} </h3> </div>)
}
}
----------------------------------------------------------------
2 函数式组件 == 无状态组件
----------------------------------------------------------------
1 ES5 的方式
function P2() {
return (<div> <h3> 单方面的付出不是爱情 </h3> </div>)
}
2 ES6 箭头函数的方式
const P3 = () => {
return (<div> <h3> 爱情里卑微的人永远得不到爱 </h3> </div>)
}
3 ES6 箭头函数的简写
const P4 = () => (<div> <h3> 爱情从来不是同情和感动 </h3> </div>)
------------------------------------------------------------------------------
组件传值
1 父子组件传值
----------------------------------------------------------------
1 书写子组件元素的时候, 自定义属性: <A1 msg={
'data'}/>
2 在子组件中: props.msg
3 各种组件中的接收示例
1 class类组件: constructor(props) {
super(props)} --> <h3>{
this.props.msg}</h3>
2 ES5函数式组件: function A1(props) {
let {
msg} = props}
3 ES6函数式组件: const A2 = props => {
props.msg}
4 ES6函数简写: const A3 = ({
msg}) => ( msg)
----------------------------------------------------------------
2 子父组件传值
----------------------------------------------------------------
1 书写子组件元素的时候, 自定义事件: <A1 onTest={
(data)=>{
Fn(data)}}/>
2 在子组件中: props.onTest('data')
3 逻辑理解
1 父组件中定义了事件方法 Fn, 当自定义事件调用的时候就会触发 Fn
2 这样把自定义事件传给子组件, 在子组件中调用自定义事件, 本质上就是调用了 Fn
3 在自定义事件调用的过程中, 可以把数据以参数的形式传给父组件的 Fn, 达到子父传数据的效果
4 代码分析
1 相当于给自定义属性 onTest, 赋值成为了一个箭头函数
2 那么 props.onTest == (data)=>{
Fn(data)} --> 然后执行这个函数, 并传参
3 执行这个自定义函数 onTest()的时候, 又去触发了父组件中的 Fn方法, 数据参数顺利到达 Fn
----------------------------------------------------------------
class 类组件中的 state
class类组件中的数据: this.state = {
num: 250}
1 访问变量: this.state.num / let {
num} = this.state
2 修改数据: this.setState(num: 66)
3 修改数据: this.setState(state =>({
num: num+1}))
4 理解
1 不把外部的 props 和自有的 state 交叉赋值
2 不可以使用 this.setState()方法的位置
1 render() + constructor() + componentDidUpdate()
2 自己封装的渲染方法中
3 每次调用 this.setState()方法, 都会触发 diff运算
4 diff 运算干什么的
1 计算出 DOM中真正变化的部分, 只针对该部分做原生 DOM操作, 而非重新渲染整个页面
2 脏节点: 就是 DOM中发生变化的那个节点
3 所以也可以说, diff 运算只会对脏节点进行操作, 而不会影响其他节点
事件绑定
1 常识问题
1 所有事件必须以 on开头 (包括自定义事件)
2 事件处理函数的定义位置, 和 render / return 同级, 在组件内部
3 若事件处理函数接收多个参数, 则最后一个参数默认为事件对象
2 绑定事件的方式
1 <button onClick={
(e)=>{
console.log('事件对象', e)}}>按钮</button>
2 <button onClick={
()=>ck1()}></button>
3 class 类组件的绑定事件方式
1 <div onClick={
this.ck1(7)}></div>
2 <div onClick={
()=>this.ck1(7)}></div>
3 <div onClick={
this.ck1.bind(this, 7)}></div>
4
渲染相关
1 条件渲染
--------------------------------------------------------------------------
获取变量: bol (布尔值)
1 {
bol && <h3>哈士奇</h3>}
2 {
bol ? <h3>大乌龟</h3> : <h3>小猫猫</h3>}
3 {
idx===1 && <h3>呵呵</h3> } / {
idx===2 && <h3>哈哈</h3>}..
4 上述3的情况, 通常使用 switch语句来封装函数, 也叫自定义的视图渲染方法(效率好一点)
--------------------------------------------------------------------------
2 动态渲染
--------------------------------------------------------------------------
1 <h2 className={
hh}>默晞</h2>
2 <h2 style={
{
color:'red', fontSize: 35px}}>默晞<h2/>
3 实现显示隐藏功能 ( 或者通过更改类名都是可以的)
1 定义变量: display
2 <h3 style={
{
display}}>呵呵</h3>
--------------------------------------------------------------------------
3 列表渲染
--------------------------------------------------------------------------
1 组件内的声明式变量
list: [ {
id:1, name: '不甘'},
{
id:2, name: '疯子'} ]
2 渲染数组最常用的方式 (数据处理函数)
fn() {
return list.map(ele=>(<div key={
ele.id}>{
ele.name}</div>))}
render() {
return(<div> {
fn()} </div>)}
--------------------------------------------------------------------------
表单
1 非受控表单 -- 用于文件上传 ( 因为所需内存大, 赋值到变量上是不科学的)
---------------------------------------------------------------------
<div>
<input id='ipt' type="text"/>
<input ref='pass' type="password"/>
<input type="file"/>
<button onClick={
()=>this.submit()}></button>
</div>
submit() {
const data = {
name: document.getElementById('ipt').value
password: this.refs.pass.value }
}
---------------------------------------------------------------------
2 受控表单 -- React推介使用 -- (通过声明式变量绑定表单值, 且实现数据双向绑定)
---------------------------------------------------------------------
1 基础使用
this.state = {
name: ''}
nameChange(e) {
this.setState({
name: e.target.value})}
<input value={
this.state.name} onChange={
(e)=>this.nameChange(e)} type="text"/>
2 方法复用操作 -- 这样其他表单也可以通过这个方法实现数据双向绑定了
formChange(e, key) {
this.state({
[key]: e.target.value}) }
<input
value={
this.state.name}
onChange={
(e)=>this.formChange(e, 'name')}
type="text"/>
<input
value={
this.state.password}
onChange={
(e)=>this.formChange(e, 'password')}
type="password"/>
---------------------------------------------------------------------
样式定义
1 直接定义样式
---------------------------------------------------------------------
src/pages/A1.js
1 <he style={
{
fontSize: '20px', color: 'red'}}></h3>
2 const hh = {
fontSize: '20px', color: 'red'}
<he style={
hh}></h3>
---------------------------------------------------------------------
2 创建单独的样式文件
---------------------------------------------------------------------
1 src/assets/A1.css
1 div {
color: red}
2 src/pages/A1.js
1 import '../assets/A1.css'
---------------------------------------------------------------------
3 使用插件: styled-components
---------------------------------------------------------------------
1 作用: 可以让我们在 JS文件中, 写 css样式 (可以很好的解决样式冲突的问题)
2 安装: npm i styled-components -S
3 文件设置: src/pages/styledCss.js
1 import styled from 'styled-components'
2 const Div1 = styled.div`font-size: 100px; color: red`
3 export {
Div1}
4 使用样式
1 import {
Div1} from './styledCss'
2 <Div1> <h3>呵呵</h3> </Div1>
---------------------------------------------------------------------