最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React学习摘要

    正文概述 掘金(大田酱紫)   2020-12-15   471

    简介

    React.js 不是一个框架,它只是一个库。它只提供 UI (view)层面的解决方案。在实际的项目当中,它并不能解决我们所有的问题,需要结合其它的库,例如 Redux、React-router 等来协助提供完整的解决方法。

    render () {
      return (
        <div>
          <h1>React 小书 {(function () { return 'is good'})()}</h1>
        </div>
      )
    }
    

    注意,直接使用 class 在 React.js 的元素上添加类名如

    这种方式是不合法的。因为 class 是 JavaScript 的关键字,所以 React.js 中定义了一种新的方式:className 来帮助我们给元素添加类名。

    还有一个特例就是 for 属性,例如 Male,因为 for 也是 JavaScript 的关键字,所以在 JSX 用 htmlFor 替代,即 Male。而其他的 HTML 属性例如 style 、data-* 等就可以像普通的 HTML 属性那样直接添加上去。

    render () {
      const isGoodWord = true
      return (
        <div>
          <h1>
            React 小书
            {isGoodWord
              ? <strong> is good</strong>
              : <span> is not good</span>
            }
          </h1>
        </div>
      )
    }
    

    如果你在表达式插入里面返回 null ,那么 React.js 会什么都不显示,相当于忽略了该表达式插入。

    renderGoodWord (goodWord, badWord) {
      const isGoodWord = true
      return isGoodWord ? goodWord : badWord
    }
    
    render () {
      return (
        <div>
          <h1>
            React 小书
            {this.renderGoodWord(
              <strong> is good</strong>,
              <span> is not good</span>
            )}
          </h1>
        </div>
      )
    }
    

    组件组合

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    
    class Title extends Component {
      render () {
        return (
          <h1>React 小书</h1>
        )
      }
    }
    
    class Header extends Component {
      render () {
        return (
        <div>
          <Title />
          <h2>This is Header</h2>
        </div>
        )
      }
    }
    
    class Main extends Component {
      render () {
        return (
        <div>
          <h2>This is main content</h2>
        </div>
        )
      }
    }
    
    class Footer extends Component {
      render () {
        return (
        <div>
          <h2>This is footer</h2>
        </div>
        )
      }
    }
    
    class Index extends Component {
      render () {
        return (
          <div>
            <Header />
            <Main />
            <Footer />
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <Index />,
      document.getElementById('root')
    )
    

    组件标签使用大写字母开头

    事件触发例子

    class Title extends Component {
      handleClickOnTitle () {
        console.log('Click on title.')
      }
    
      render () {
        return (
          <h1 onClick={this.handleClickOnTitle}>React 小书</h1>
        )
      }
    }
    

    事件触发方法内调用

    传入一个event 对象

    事件通常与函数结合使用,函数不会在事件发生前被执行!

    class Title extends Component {
      handleClickOnTitle (e) {
        console.log(e.target.innerHTML)
      }
    
      render () {
        return (
          <h1 onClick={this.handleClickOnTitle}>React 小书</h1>
        )
      }
    }
    

    事件中使用当前实例,在事件方法中this是不会返回当前实例的,可以使用:

    class Title extends Component {
      handleClickOnTitle (e) {
        console.log(this)
      }
    
      render () {
        return (
          <h1 onClick={this.handleClickOnTitle.bind(this)}>React 小书</h1>
        )
      }
    }
    

    这种 bind 模式在 React.js 的事件监听当中非常常见,bind 不仅可以帮我们把事件监听方法中的 this 绑定到当前组件实例上;还可以帮助我们在在渲染列表元素的时候,把列表元素传入事件监听函数。

    class Title extends Component {
      handleClickOnTitle (word, e) {
        console.log(this, word)
      }
    
      render () {
        return (
          <h1 onClick={this.handleClickOnTitle.bind(this, 'Hello')}>React 小书</h1>
        )
      }
    }
    

    向事件处理程序传递参数

    <button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
    <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
    

    分别通过箭头函数和 Function.prototype.bind 来实现。

    关于setState()更新状态信息

    
      constructor (props) {
        super(props)
        this.state = {
          name: 'Tomy',
          isLiked: false
        }
      }
    
      handleClickOnLikeButton () {
        this.setState({
          isLiked: !this.state.isLiked
        })
      }
    

    第二种使用方式可以解决这个问题,React.js 会把上一个 setState 的结果传入这个函数,你就可以使用该结果进行运算、操作,然后返回一个对象作为更新 state 的对象:

    handleClickOnLikeButton () {
        this.setState((prevState) => {
          return { count: 0 }
        })
        this.setState((prevState) => {
          return { count: prevState.count + 1 } // 上一个 setState 的返回是 count 为 0,当前返回 1
        })
        this.setState((prevState) => {
          return { count: prevState.count + 2 } // 上一个 setState 的返回是 count 为 1,当前返回 3
        })
        // 最后的结果是 this.state.count 为 3
      }
    

    上面我们进行了三次 setState,但是实际上组件只会重新渲染一次,而不是三次;

    可配置性

    通过props来进行配置

    class LikeButton extends Component {
      constructor () {
        super()
        this.state = { isLiked: false }
      }
    
      handleClickOnLikeButton () {
        this.setState({
          isLiked: !this.state.isLiked
        })
      }
    
      render () {
        const likedText = this.props.likedText || '取消'
        const unlikedText = this.props.unlikedText || '点赞'
        return (
          <button onClick={this.handleClickOnLikeButton.bind(this)}>
            {this.state.isLiked ? likedText : unlikedText} ?
          </button>
        )
      }
    }
    

    设定属性

    class Index extends Component {
      render () {
        return (
          <div>
            <LikeButton likedText='已赞' unlikedText='赞' />
          </div>
        )
      }
    }
    
       <LikeButton wordings={{likedText: '已赞', unlikedText: '赞'}} />
    

    传入方法

    class Index extends Component {
      render () {
        return (
          <div>
            <LikeButton
              wordings={{likedText: '已赞', unlikedText: '赞'}}
              onClick={() => console.log('Click on like button!')}/>
          </div>
        )
      }
    }
    

    调用方法

    handleClickOnLikeButton () {
        this.setState({
          isLiked: !this.state.isLiked
        })
        if (this.props.onClick) {
          this.props.onClick()
        }
      }
    

    默认参数

    class LikeButton extends Component {
      static defaultProps = {
        likedText: '取消',
        unlikedText: '点赞'
      }
    
      constructor () {
        super()
        this.state = { isLiked: false }
      }
    
      handleClickOnLikeButton () {
        this.setState({
          isLiked: !this.state.isLiked
        })
      }
    
      render () {
        return (
          <button onClick={this.handleClickOnLikeButton.bind(this)}>
            {this.state.isLiked
              ? this.props.likedText
              : this.props.unlikedText} ?
          </button>
        )
      }
    }
    

    如果没有传进来,会直接使用 defaultProps 中的默认属性。

    props 一旦传入进来就不能改变

    组件的使用者可以主动地通过重新渲染的方式把新的 props 传入组件当中,这样这个组件中由 props 决定的显示形态也会得到相应的改变。

    不允许修改的方法

    handleClickOnLikeButton () {
        this.props.likedText = '取消'
      }
    

    允许修改的方法

    handleClickOnChange () {
        this.setState({
          likedText: '取消',
          unlikedText: '点赞'
        })
      }
    

    列表渲染

    const users = [
      { username: 'Jerry', age: 21, gender: 'male' },
      { username: 'Tomy', age: 22, gender: 'male' },
      { username: 'Lily', age: 19, gender: 'female' },
      { username: 'Lucy', age: 20, gender: 'female' }
    ]
    
    class Index extends Component {
      render () {
        const usersElements = [] // 保存每个用户渲染以后 JSX 的数组
        for (let user of users) {
          usersElements.push( // 循环每个用户,构建 JSX,push 到数组中
            <div>
              <div>姓名:{user.username}</div>
              <div>年龄:{user.age}</div>
              <div>性别:{user.gender}</div>
              <hr />
            </div>
          )
        }
    
        return (
          <div>{usersElements}</div>
        )
      }
    }
    
    ReactDOM.render(
      <Index />,
      document.getElementById('root')
    )
    

    简化写法

    class Index extends Component {
      render () {
        return (
          <div>
            {users.map((user) => {
              return (
                <div>
                  <div>姓名:{user.username}</div>
                  <div>年龄:{user.age}</div>
                  <div>性别:{user.gender}</div>
                  <hr />
                </div>
              )
            })}
          </div>
        )
      }
    }
    

    对于用表达式套数组罗列到页面上的元素,都要为每个元素加上 key 属性,这个 key 必须是每个元素唯一的标识。

    const todoItems = todos.map((todo, index) =>
      // Only do this if items have no stable IDs
      <li key={index}>
        {todo.text}
      </li>
    );
    

    在 map() 方法中的元素需要设置 key 属性。

    构造函数

    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }
     }
    

    生命周期方法

    componentDidMount() 方法会在组件已经被渲染到 DOM 中后运行

    一旦 Clock 组件从 DOM 中被移除,React 就会调用 componentWillUnmount() 生命周期方法

    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }
    
      componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
      }
    
      componentWillUnmount() {
        clearInterval(this.timerID);
      }
    
      tick() {
        this.setState({
          date: new Date()
        });
      }
    
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Clock />,
      document.getElementById('root')
    );
    

    根据单一功能原则来判定组件的范围。也就是说,一个组件原则上只能负责一个功能。如果它需要负责更多的功能,这时候就应该考虑将它拆分成更小的组件。

    参考文章:

    react.docschina.org/docs/hello-…

    huziketang.mangojuice.top/books/react…


    起源地下载网 » React学习摘要

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元