慕课网基于实例的React16傻瓜式教程笔记

一、配置开发环境+React 第一个组件

1、配置开发环境

npm i create-react-app -g

create-react-app myproject

cd myproject

npm start

当然有 cnpm 和 yarn 的可以用 cnpm 和 yarn  start

2、React第一个组件(Hello React)

// Welcome.js
import React from'react'
class Welcome extends React.Component {
    render(){
        return <h1> Hello React</h1>
    }
}
export default Welcome
//导入Welcome.js
import React from 'react';
import ReactDOM from 'react-dom';
import Welcome from './Welcome'
ReactDOM.render(<Welcome />, document.getElementById('root'));

运行结果

二、JSX

1、第一部分

(1)JSX的主要语法只有花括号的概念,在花括号里面可以添加任何的js表达式

(2)

     <h1> Hello React</h1>
     {/* Hello React */}

     {[1,2,3]} 
     {/* 123 */}

     { <p> this is jsx </p>} 
     {/* this is jsx 花括号里面也是表达式,只不过没有花括号是一样的效果 */}

(3)todolist

render(){
        const todolist=['恰饭','睡觉']
        return (
            <div>
             <ul>
                {
                  todolist.map(item=> <li>{item}</li> )
                }
            </ul>
            </div>
        )
       
    }

运行结果

这里顺便巩固了箭头函数的用法

① item单个参数可以加括号也可以不加

② 箭头后面如果加花括号必须加return 即  tags.map(item=> {item}) 错误

③ 正确写法有 tags.map(item=> item) 、tags.map(item=> (item)) 、tags.map(item=> (<li>{item}</li>)) 

(3)三元表达式 {isLogin?<p>你已经登录</p>:<p>请登录</p>}

(4)属性: class变成className    for 变成htmlFor

2、第二部分

(1) jsx 它是一种语法糖 ——React.createElement(

(2)返回的是ReactElement对象

(3)babel:  ES6——> ES5

三、React属性+状态+生命周期+表单

1、属性

(1)组件像一个函数一样,接受特定的输入(props),产出特定的输出(React elements)

(2)装bootstrap美化组件 :

cnpm install bootstrap --save

(3)一张名片组件

//NameCard.js
import React from 'react'
class NameCard extends React.Component {
   
    render(){
        const {name,tel,isAlien,tags} = this.props  
        return (
            <div className='alert alert-success'>
                <h4 className='alert-heading'>{name}</h4>
                <ul>
                    <li>电话:{tel}</li>
                    <li>{isAlien?'外星生物':'人类'}</li>  
                </ul>
                <hr/>
                 <p>好友印象:{tags.map((item,index)=>(<span className='badge badge-pill badge-primary' key={index}>{item}</span>))}</p>

            </div>

        )
    }
}
export default NameCard
// App.js
import React from 'react';
import NameCard from'./components/NameCard';

function App() {
  const tags=['体育健将','单机游戏爱好者']
  return (
    <div className="App">
     
      <NameCard name='king' tel={13012121212} isAlien tags={tags}></NameCard>
    </div>
  );
}

export default App;

     

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import 'bootstrap/dist/css/bootstrap.min.css'
ReactDOM.render(<App />, document.getElementById('root'));

从名片组件中学到的东西:

① const {name,tel,isAlien,tags} = this.props 对象不是数组,花括号不是大括号

② <li>{isAlien?'外星生物':'人类'}</li>  花括号里面的文字要加引号,是字符串不是变量

③  map是数组的方法,有一个参数,参数是一个函数,函数中有3个参数

array.map(function(item,index,arr){})

参数1:item必须。当前元素的值

参数2:index,可选。当前元素在数组中的索引值

参数3:arr可选。当前元素属于的数组对象

④ App.js要导入 NameCard.js 而且要起名字 import NameCard from'./components/NameCard';

App.js和NameCard.js都不用导入bootstrap只需要index.js导入即可

⑤ const的定义要在render()里面 return()外面

⑥ 变成function定义:const NameCard= (props)=>{ }   注意:function()不可,不能function等于function(箭头函数本质是function())

⑦<p>好友印象:{tags.map((item,index)=>(<span className='badge badge-pill badge-primary' key={index}>{item}</span>))}</p> 箭头右边只能用小括号而不能用花括号!!!!也可不加括号!

(4)属性是只读的

(5)纯函数:写的非常好的一篇链接 https://blog.csdn.net/c_kite/article/details/79138814

简单来说不会改变自己参数的输入值

React规定必须像使用纯函数那样使用props,所以props是只读的。

2、状态

(1)this.setState({ object })方法是更新state的唯一途径

(2)"点赞+1"组件

import React from 'react'
class LikesButton extends React.Component {
      constructor(props){
          super(props)
          this.state= {
              likes:0
          }
    // 第一种方法:  this.increaseLikes=this.increaseLikes.bind(this)
      }
    increaseLikes(){
        this.setState({
            likes:++this.state.likes
        })
    }
    render(){
        return(
            <div>
             {  /*第一种方法: <button onClick={this.increaseLikes} className='btn btn-outline-primary btn-lg' type='button'>
             赞 {this.state.likes}
             </button> */}
             <button onClick={()=>this.increaseLikes()} className='btn btn-outline-primary btn-lg' type='button'>
             赞 {this.state.likes}
             </button>
            </div>
        )
    }
    }  
export default LikesButton

从“点赞+1组件”学到的东西:

① js类中的方法不会自动绑定 解决办法有在constructor中预先进行绑定和利用箭头函数(都在代码中体现了)

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,例如,f.bind(obj),实际上可以理解为obj.f(),这时,f函数体内的this自然指向的是obj

② 注意constructor 和render的顺序 、两种方法中onClick函数的写法、this.state.likes++是错的(会一直不变)、以及increaseLikes方法前面没有this 

③ ES6 要求,子类的构造函数必须执行一次 super() 函数。super()作用是,代表调用了父类的构造方法,函数返回了子类的实例。因为子类的构造方法是根据父类构建的,因此this关键字必须在调用super()函数之后使用,否则会报错。并且子类构造函数内必须调用super()方法。

3、React生命周期

(1)组件初始化 组件更新 组件卸载

(2)电子钟组件

import React from 'react'
class DigitalClock extends React.Component {
      constructor(props){
          super(props)
          this.state= {
              data:new Date()
          }
      }

      componentDidMount(){
          this.timer=setInterval(()=>{
             this.setState({
             data :new Date()
             })
            },1000)
         
      }
      componentDidUpdate(currentProps,currentState){
        console.log(currentState);
        
      }
      componentWillMount(){
        clearInterval(this.timer)
      }   
     render(){
            return(
            <div className='jumbotron'>
             <h1>{this.state.data.toLocaleTimeString()}</h1>
            </div>
            )
        }
      }

export default DigitalClock

从电子钟组件中学到的东西:

① toLocaleTimeString() 方法可根据本地时间把 Date 对象的时间部分转换为字符串,并返回结果

②componentDidUpdate()方法会传入两个参数:prevPropsprevState

③ 注意DidMount的写法,好难啊!

4.表单

(1)只有React控制输入的表单元素——>受控组件 太繁琐——>改成非受控组件(减少代码量

(2)留言框组件

import React from 'react'
class CommentBox extends React.Component {
      constructor(props){
          super(props)
          this.handleSubmit=this.handleSubmit.bind(this)
      }
      
      handleSubmit(e){
        alert(this.inputtext.value)
        e.preventDefault()
      }      
      render(){
          return(
              <form onSubmit={this.handleSubmit}>         
             <div>
                  <label htmlFor="">留言内容</label> <br/>
                  <input ref={(inputtext)=>{this.inputtext=inputtext}} placeholder='请输入内容' type="text" />
             </div>  
                  <button type="submit" className='btn btn-primary'>留言</button>
             
              </form>
          )
      }
    
    }
export default CommentBox 

留言框组件学到的东西:

① ref属性的inputtext获取了dom元素,可以拿到input的值

② e.preventDefault() 防止默认跳转   即不会出现 /?

四、综合实例——留言本

1.实例分析

(1)React中的状态提升概括来说,就是将多个组件需要共享的状态提升到它们最近的父组件上.在父组件上改变这个状态然后通过props分发给子组件.

(2)在 React 中,数据是自顶而下单向流动的,即从父组件到子组件。这条原则让组件之间的关系变得简单且可预测。

2.代码实现

//CommentBox.js
import React from 'react'
class CommentBox extends React.Component {
      constructor(props){
          super(props)
          this.handleSubmit=this.handleSubmit.bind(this)
      }
      handleSubmit(e){
        this.props.addComment(this.inputtext.value)
        e.preventDefault() 
      }  
      render(){
          return(
              <form onSubmit={this.handleSubmit}>         
             <div>
                  <label htmlFor="">留下评论</label> <br/>
                  <input ref={(inputtext)=>{this.inputtext=inputtext}} placeholder='请输入内容' type="textarea" /> 
             </div>   <br/>
                  <button type="submit" className='btn btn-primary'>发表</button> 
                  已有{this.props.value.length}条评论
             
              </form>
          )
      }
    
    }
export default CommentBox 

//CommentList.js
import React from 'react'
class CommentList extends React.Component {
      constructor(props){
          super(props)  
      }
      render(){
          return(
           
            <div>
              <label>评论列表</label> <br/>
              <ul className='list-group mb-3'>
                  {this.props.value.map(
                      (item,index)=><li className='list-group-item' key={index}>{item }</li>
                      )}
              </ul>
              </div>
             
          )
      }

    }
    export default CommentList    

 //App.js
import React from 'react';
import CommentList from './components/CommentList';
import CommentBox from './components/CommentBox';
class App extends  React.Component{
     constructor(props){
     super(props)
     this.state={
       comment:['真是太好看了']
     }
     this.addComment=this.addComment.bind(this)
    }
    addComment(inputtex){
      this.setState({
        comment:[...this.state.comment,inputtex]
      })
       
      }
          

     render(){
     return (
    <div>
      <CommentList value={this.state.comment}></CommentList>
      <CommentBox value={this.state.comment} addComment={this.addComment}></CommentBox>
    </div>
  )
}
 
}

export default App;

从留言本组件学到的东西:

① 如果用function可以接收具体属性作为参数

② 循环输出一定记得带key(index)

③ 展开运算符合并数组(追加)

如果你想要整合两个数组,并且想把某个数组放在另一个数组的任意特定位置上,你可以这么做:

var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];

// ["one", "two", "three", "four", "five"]

这是一种比其他方式更短的语句!...arr1 代表了arr1数组中的元素

对比在本例中 comment:[...this.state.comment,inputtex]

五、Context

1、Context介绍

(1)Props属性时由上到下单向传递的,过程繁琐,Context提供了在组件中共享此类值的方法

(2)React 16.3以上,React16之后都叫React Fiber

(3)设计目的是共享哪些对于组件来说是全局数据(主题、语言等)但是不要仅仅为了避免一两个层级传递就是用Context

2、Context实例

坑(暂时未看)

发布了27 篇原创文章 · 获赞 0 · 访问量 2122
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览