React 类组件和函数组件

组件(Component)

1、组件:能跟其他物件组合起来的物件
2、就目前而言,一个返回React元素的“函数”就是组件
3、在Vue里,一个构造选项就可以表示一个组件

元素与组件
元素:const div = React.createElement('div',...)
//这是一个React元素(d是小写的)
组件:const Div = ()=>React.createElement('div'..)
//这是一个React组件(D是大写的)

React 的两种组件

1、类组件

class Son extends React.Component {
  constructor() {
    super();
    this.state = {
      n: 0
    };
  }

  add() {
    this.setState({ n: this.state.n + 1 });
  }

  render() {
    return (
      <div className="Son">
        儿子n :{this.state.n}
        <button onClick={() => this.add()}>+1</button>
        <Grandson />
      </div>
    );
  }
}

类组件注意事项:

  • this.state.n += 1 无效?
    //其实n已经变了,UI没自动更新,
    //调用 setState 才会触发更新(异步更新,这里复制原有n,得到一个新的n)
    //React不不像Vue一直监听data 所以不会更新
  • setState 会异步更新UI
    //setState 之后,state不会立马改变,立马读会失败
    //推荐使用setState(函数)

2、函数组件

const Grandson = () => {
  const [n, setN] = React.useState(0);
  return (
    <div className="Grandson">
      孙子n:{n}
      <button onClick={() => setN(n + 1)}>+1</button>
    </div>
  );
};

函数组件注意事项:
没有 this,一律使用参数和变量

组件使用方法:

  • <Welcome />会被翻译成什么

  • <div />会被翻译为React.createElement('div')

  • <Welcome />翻译为React.createElement(Welcome)

  • 可以用babel online直接翻译给你看

  • React.createElement的逻辑

  • 如果传入一个字符串div, 则会创建div

  • 如果传入一个函数,则会调用该函数,获取其返回值

  • 如果传入一个类,则在类前面加个new(这会导致执行constructor), 获取一个组件对象,然后调用对象的render方法,获取其返回值

props - 外部数据

const root =document.getElementById('root')
const React = window.React
const ReactDOM = window.ReactDOM
// import React from 'react'
// import ReactDOM from 'react-dom'

function App(){
  return(
    <div className="App">
      爸爸
      <Son x="吃饭"/>
    </div>
  )
}

class Son extends React.Component{
  constructor(){
    super()
    this.state = {
      n:0
    }
  }
  add(){
    this.setState({n:this.state.n+1})
  }
  render(){
    return(
      <div>
        儿子 n:{this.state.n},{this.props.x} //---------类组件直接用this.props接收值
        <button onClick={()=>this.add()}> +1 </button>
        <Grandson y="睡觉"/>
      </div>
    )
  }
}

const Grandson =(props) =>{
  const [n,setN] = React.useState(0)
  return(
    <div>
      孙子 n:{n},{props.x}//---------函数组件接收一个props的参数不需要this就可以接收值
      <button onClick={()=>setN(n+1)}> +1 </button>
    </div>
  )
}
ReactDOM.render(App(),root);

state - 内部数据

  • 链接
  • 类组件用this.state读,this.setState写
  • 函数组件用useState返回数组,第一项读,第二项写
  • 关注数据的时候我们需要关注,初始化,怎么读,怎么写
  • 直接改state的n,ui不会刷新,vue里面是对data做了劫持,必须要用setState,
  • 另外不推荐对象局部改变了,又原封不动的给setState,效果是ok的但是一般推荐要产生一个新的对象
  • 这就叫做数据不可变,以前的数据不要改,要改就产生一个新的对象
    this.setState({ n: this.state.n + 1 });
  • 牛x的前端用setState(函数),这样写的好处,打印n的值发现不对,因为setState是异步的更新ui的过程,好处就是避免异步造成的误解
this.setState((state)=>{
  return {n: state.n+1}
})

// 如果用这种写法就很清楚的知道旧的state和新的state
// 打印n
this.setState(state=>{
  const n = state.n + 1
  console.log(n)
  return {n}
})

setState 注意事项

  • this.state.n += 1无效?
  • 其实n已经改变了,只不过UI不会自动更新而已
  • 调用setState才会触发UI更新(异步更新)
  • 因为React没有像Vue监听data一样监听state
  • setState会异步更新UI
  • setState之后,state不会马上改变,立马读state会失败
  • 更推荐的方式是setState(函数),函数接受一个旧的state返回一个新的state
  • this.setState(this.state)不推荐
  • React希望我们不要修改旧state(不可变数据)
  • 常用代码: setState({n: state.n + 1})
  • 总结,这是一种理念(函数式)
函数组件注意事项
  • 跟类组件类似的地方,也要通过setX(新值)来更新UI
  • 跟类组件不同的地方,没有this,一律用参数和变量

复杂的state

总结复杂的state

事件绑定

类组件的事件绑定

<button onClick={() => this.addN()}>n + 1</button>
// 传一个函数给onClick即可,注意C大写
// 思考一个问题,下面这样写行不行
<button onClick={this.addN}>n + 1</button>
// 有问题,这样使得this.addN里的this变成window
<button onClick={this.addN.bind(this)}>n+1</button>
// 这样写是可以的,因为它返回一个绑定了当前this的新函数
// 但是这样写太麻烦,你不如第一种
// 但是第一种写法依然太长,可用this._addN = ()=> this.addN()
// 给箭头函数取个名字,然后写成,在构造函数中赋值
<button onClick={this._addN}>n+1</button>
// 给箭头函数取个名字,然后写成
<button onClick={this._addN}>n + 1</button>
// 这样又不如写成
constructor() {
  this.addN = ()=> this.setState({n: this.state.n + 1})
}
render(){
  return <button onClick={this.addN}>n + 1</button>
}

但这样写不如声明addN结构清晰
最终的方案,类组件的事件绑定最好的方法

class Son extends React.Component {
  addN = () => this.setState({n: this.state.n + 1});
  render() {
    return <button onClick={this.addN}>n+1</button>
  }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容