React——学习总结

简单开始例子

ReactDOM.render(                   //React DOM 得render方法
  <h1>Hello, world!</h1>,          //渲染到html DOM节点得react元素
  document.getElementById('root')  //获取html页面得DOM节点
);

JSX

JSX, 一种 JavaScript 的语法扩展 React.createElement(component, props, ...children)得语法糖,因此须要先引用 React变量。 咱们推荐在 React 中使用 JSX 来描述用户界面。JSX 乍看起来可能比较像是模版语言,但事实上它彻底是在 JavaScript 内部实现的。

一、JSX中使用JavaScript 表达式用大括号{}包起来;
二、if 或者 for 语句里使用 JSX,将它赋值给变量,看成参数传入,做为返回值均可以;
三、JSX 换行和缩进时,代码的外面扩上一个小括号,这样能够防止 分号自动插入 的 bug;
四、JSX 标签是闭合式的;
五、camelCase 小驼峰命名 来定义属性的名称 className,backGround;
六、全部的内容在渲染以前都被转换成了字符串,有效地防止 XSS(跨站脚本) 攻击;
七、注释语法:{/**/}
八、JSX 标签名不能为一个表达式,能够先赋值给一个变量。
九、没有给属性传值,它默认为 truehtml

const element = (//换行用小括号括起来
  <div>
    <h1 className={aclass}>Hello!</h1> {/*属性用小驼峰命名方式,变量aclass用{}括起来*/}
    <h2>{2+2}</h2>                     {/*js表达式用{}括起来*/}
  </div>
);
//能够用点表示法来引用 React 组件
import React from 'react';
const MyComponents = {//一个模块包含多个组件。
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker(props) {

  return <MyComponents.DatePicker color="blue" checked />;//点表示法 checked 值为true
  //return <MyComponents[props.componentTtye] color="blue" />;错误:JSX 标签名不能为一个表达式
  //const componentType = MyComponents[props.componentTtye] ;return <componentType color="blue" />  //正确。
}

元素渲染

一、元素是构成 React 应用的最小单位;
二、大多数React应用只会调用一次 ReactDOM.render();
三、React DOM 首先会比较元素内容前后的不一样,而在渲染过程当中只会更新改变了的部分;

组件 & Props

一、组件得含义与定义react

组件能够将UI切分红一些的独立的、可复用的部件,从概念上看就像是 函数,它能够接收任意的参数(称之为“props”),全部的React组件必须像 纯函数那样使用它们的props( 不可修改)。并 返回一个须要在页面上展现的 React元素
//函数定义组件
function Welcome(props) {//参数props
  return <h1>Hello, {props.name}</h1>;//返回react 元素
}
//ES6 class定义组件
class Welcome extends React.Component { //扩展ES6类React.Component
  render() {//render()函数体
    return <h1>Hello, {this.props.name}</h1>;
  }
}
当React遇到的元素是用户自定义的组件,它会将 JSX属性做为单个对象(props)传递给该组件,这个对象称之为“ props”。组件名 首字母大写,使用该组件时必须 定义或引入它。
function Welcome(props) {              //自定义组件
  return <h1>Hello, {props.name}</h1>;//props={name:"Sara"}
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,                            //元素为自定义组件Welcome
  document.getElementById('root')
);

二、组合组件express

组件能够在它的输出中引用其它组件,React应用中,按钮、表单、对话框、整个屏幕的内容等,这些一般都被表示为组件。组件的返回值只能有一个根元素。
function App() {
  return (
    <div>{/*一个根元素*/}
      <Welcome name="Sara" />{/*引用自定义Welcome组件*/}
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

State & 生命周期

一、state数组

一、局部状态State:一个功能只适用于类定义组件;
二、 构造函数(constructor)是惟一可以初始化 this.state 的地方;
三、应当使用 setState()更新局部状态,而不是直接更改this.state得值;
四、this.props 和 this.state 多是 异步更新,不能用他们来计算this.state得下一个值,应该用
setState回调函数得方式传入参数 (prevState, props),return一个对象;
六、当你调用 setState() 时,React 将你提供的对象合并到当前状态,更新其中一个(state.name)属性时,会将该属性合并到this.state对象中;
七、 自顶向下单向数据流,任何状态始终由某些特定组件全部,而且从该状态导出的任何数据或 UI 只能影响树中 下方的组件

二、生命周期异步

挂载:组件加载到DOM中,
卸载:生成的DOM被移除。
生命周期钩子:componentWillUnmount()挂载前, componentDidMount()挂载后
class Clock extends React.Component {
  constructor(props) {                //基础构造函数
    super(props);                     //传递props
    this.state = {date: new Date()};  //惟一初始化this.state得地方
  }

  componentDidMount() {//react 元素添加到DOM中后
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {//react 元素即将从DOM中删除
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({  //更改state得值
      date: new Date()
    });
   /*回调函数得方式更改state得值
     this.setState((prevState, props) => ({
      date: prevState.date + 1
    }));*/
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{/*每次state更新时调用render方法从新渲染值*/}
      </div>
    );
  }
}

ReactDOM.render(//初次调用render渲染clock组件到DOM中
  <Clock />,
  document.getElementById('root')
);

事件处理

一、React事件绑定属性的命名采用 驼峰式写法,而不是小写;
二、若是采用 JSX 的语法你须要 传入一个函数做为事件处理函数,而不是一个字符串(DOM元素的写法);
三、在 React 中另外一个不一样是你不能使用返回 false 的方式阻止默认行为。你必须明确的使用 e.preventDefault();
四、类的方法默认是不会绑定 this,没有在方法后面添加 (),要为这个方法绑定 this,( 构造函数中绑定,属性初始化器法, 箭头函数), 箭头函数,若是这个回调函数做为一个属性值传入低阶组件,这些组件可能会进行额外的从新渲染。建议选用其余两种方法。
五、传参数:参数 e 做为 React 事件对象将会被做为第二个参数进行传递。经过 箭头函数的方式, 事件对象e必须 显式的进行传递,可是经过 bind 的方式,事件对象以及更多的参数将会被 隐式的进行传递。
class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {//属性初始化器法绑定this
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
class LoggingButton extends React.Component {
/*构造函数中绑定this
    constructor(props) {
        super(props);
        // This binding is necessary to make `this` work in the callback
        this.handleClick = this.handleClick.bind(this);
   }*/
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e,id)}>{/*箭头函数方法,用构造函数中绑定this时可直接调用this.handleClick*/}
        Click me
      </button>
    );
  }
}

条件渲染

一、使用 JavaScript 操做符 if 或条件运算符来建立表示当前状态的元素 知足条件return元素;
二、声明一个变量用于存储元素,渲染组件得其中一部分元素;
三、与运算符 &&:用花括号包裹代码在 JSX 中 嵌入任何表达式 ,也包括 JavaScript 的逻辑与 &&,JavaScript 中,true && expression 老是返回 expression,而 false && expression 老是返回 false,若是条件是 true,&& 右侧的元素就会被渲染,若是是 false,React 会忽略并跳过它;
四、三目运算符:condition ? true : false;
五、阻止组件渲染 :render 方法返回 null,可是 生命周期得方法依然能够回调
function WarningBanner(props) {
  if (!props.warn) {
    return null;    //返回null不渲染元素
  }
 const a = <a>超连接</a>;//存储元素到变量
  if (props.warn == “a”) {//if条件句 return元素,tia'jian渲染
    return a;    
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true}
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(prevState => ({
      showWarning: !prevState.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}{/*三目运算符选择渲染文本*/}
        </button>
        {this.props.warn=="b" && <a>b超连接</a>} // &&条件渲染
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);

列表 & Keys

一、map()
二、当你建立一个元素时,必须包括一个特殊的 key 属性。key是惟一得标识,数据里面得id或索引index,key应该绑定在循环得组件上而不是DOM元素上 key应该在数组的上下文中被指定
三、两个不一样的数组时,咱们可使用相同的键;
四、key会做为给React的提示,但不会传递给你的组件,传递给组件必须赋值在组件得属性上;
五、也可在JSX中使用map();
function ListItem(props) {
  // 对啦!这里不须要指定key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 又对啦!key应该在数组的上下文中被指定
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
      {numbers.map((number)=>
          <ListItem value={number} key={index}/> 
      )
      }
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

表单

一、受控组件(<input>,<textarea>, <select>): 每一个状态的改变都有一个与之相关的处理函数,使react变成一种单一数据源的状态,表单值为state的属性值,更改时调用事件更改state值。经过传入一个value属性来实现对组件的控制;
二、<textarea>:value属性来text内容;
三、select 标签:用value值表明选中的内容;
四、处理多个受控的input元素时,能够经过给每一个元素添加一个name属性,来让处理函数根据 event.target.name的值来选择作什么。
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value; //判断type
    const name = target.name;  //根据target.name来设定值。

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

状态提高

一、 经过将state数据提高至离须要这些数据的组件最近的父组件来完成的。这就是所谓的状态提高;
二、让组件“受控”,让组件收一个一个属性值为父组件得函数名。可在组件内调用该函数,该函数使用setState();
三、在React应用中,对应任何可变数据理应只有一个单一“数据源”。一般,状态都是首先添加在须要渲染数据的组件中。此时,若是另外一个组件也须要这些数据,你能够将数据提高至离它们最近的父组件中。你应该在应用中保持 自上而下的数据流,而不是尝试在不一样组件中同步状态。

组合 vs 继承

一、React 具备强大的组合模型,咱们建议使用组合而不是继承来复用组件之间的代码;
二、包含关系:不知道子组件是什么(Sidebar 或 Dialog),children(this.props.children) 属性将子元素直接传递到输出,该组件包含的其余元素即为children属性得值,或者将元素赋值给组件得自定义属性;
三、特殊实例:经过配置属性用较特殊的组件来渲染较通用的组件;
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}
    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}
               onChange={this.handleChange} />

        <button onClick={this.handleSignUp}>
          Sign Me Up!
        </button>
      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}
相关文章
相关标签/搜索