React小结

前言

简介

构建用户界面的JAVASCRIPT库,主要用于构建UI
起源于 Facebook 的内部项目,用来架设 Instagram 的网站,拥有较高的性能,代码逻辑非常简单,并于 2013 年 5 月开源。

特点

1.声明式设计 −React采用声明范式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSXJSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

JSX语法

const element = <h1>Hello, world!</h1>;

React 书写格式

以前使用JS 定义一个变量使用 var 现在用 const
const div = document.createElement('div');

渲染方法

所有的 js,html 都可通过它进行渲染绘制,他有两个参数,内容和渲染目标 js 对象

ReactDOM.render(<App />, div);

React 安装和构建React 开发环境

通过 npm 使用 React

$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ npm config set registry https://registry.npm.taobao.org

//使用
$ cnpm install [name]

使用 create-react-app 快速构建 React 开发环境

create-react-app 自动创建的项目是基于 Webpack + ES6

$ cnpm install -g create-react-app
$ create-react-app my-app
$ cd my-app/
$ npm start

在浏览器中打开 http://localhost:3000/

H5项目说明

简介

使用create-react-app脚手架搭建,采用react+antd+mobile技术
项目路径在H5dev 项目的 m文件里

H5项目目录

Build目录

里是 npm run build 命令后 打包存放的目录

Public

跟域名访问的目录

Src

自己开发的项目文件

Api目录

主要存放了 一下接口相关的

Components

存放了一些公用组件

Config

存放了配置文件

Images

图片

Pages

每个页面的路径

Style

样式

Utils

存放一些公用方法

Index.js

入口文件

Router.js

路由文件

Activity 存放了一些活动

常见用法

1.元素渲染

const element = <h1>Hello, world!</h1>;
ReactDOM.render(
    element,
    document.getElementById('example')
);

2.更新元素渲染

创建一个新的元素,然后将它传入 ReactDOM.render() 方法

class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>现在是 {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
 
function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('example')
  );
}
setInterval(tick, 1000);

3.元素取值和赋值

this.props.属性名 来取值。
可以多层 props 来传值,在 ReactDOM.render 定义属性值,传给调用方法 App,再在调用的ES6类调用中用 props.属性直接赋值过去。

var myStyle = {color:'red',textAlign:'center'}
class Name extends React.Component {
  render() {
    return <h1 style={myStyle}>网站名称:{this.props.name}</h1>;
  }
}
class Url extends React.Component {
  render() {
    return <h1>网站地址:{this.props.url}</h1>;
  }
}
class Nickname extends React.Component {
  render() {
    return <h1>网站地址:{this.props.nickname}</h1>;
  }
}
function App(props) {
    return (
        <div>
            <Name name={props.name}/>
            <Url  url={props.url}/>
            <Nickname  nickname={props.nickname}/>
        </div>
    );
}

多个属性的传入注意不用逗号或分号隔开而是空格符隔开:

ReactDOM.render(
     <App name={"StevenHu教程"} url={"http://www.runoob.com"} nickname={"Runoob"}/>,
    document.getElementById('example')
);

4.JSX语法

执行更快,类型安全,在编译过程中就能发现错误

const element = <h1>Hello, world!</h1>;

JSX, 一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面
JSX 是在 JavaScript 内部实现的。JSX 就是用来声明 React 当中的元素

var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));

5.独立文件

你的 React JSX 代码可以放在一个独立文件上,例如我们创建一个 helloworld_react.js 文件,代码如下

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);

在 HTML 文件中引入该 JS 文件

<body>
  <div id="example"></div>
<script type="text/babel" src="helloworld_react.js"></script>
</body>

6.JavaScript 表达式

ReactDOM.render(
    <div>
      <h1>{1+1}</h1>
    </div>
    ,
    document.getElementById('example')
);

在 JSX 中不能使用 if else 语句,但可以使用 conditional (三目运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.

ReactDOM.render(
    <div>
      <h1>{i == 1 ? 'True!' : 'False'}</h1>
    </div>
    ,
    document.getElementById('example')
);

7.样式

React 推荐使用内联样式

var myStyle = {
    fontSize: 100,
    color: '#FF0000'
};
ReactDOM.render(
    <h1 style = {myStyle}>StevenHu教程</h1>,
    document.getElementById('example')
);

8.注释

注释需要写在花括号中,实例如下:

ReactDOM.render(
    <div>
    <h1>StevenHu教程</h1>
    {/*注释...*/}
     </div>,
    document.getElementById('example')
);

9.数组

JSX 允许在模板中插入数组,数组会自动展开所有成员

var arr = [
  <h1>StevenHu教程</h1>,
  <h2>学的不仅是技术,更是梦想!</h2>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);

10.事件处理

  • React 事件绑定属性的命名采用驼峰式写法,而不是小写
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)

HTML 通常写法是:

<button onclick="activateLasers()">
  激活按钮
</button>

React 中写法为:

<button onClick={activateLasers}>
  激活按钮
</button>

11.不能使用返回 false 的方式阻止默认行为, 你必须明确的使用 preventDefault

通常我们在 HTML 中阻止链接默认打开一个新页面,可以这样写

<a href="#" onclick="console.log('点击链接'); return false">
  点我
</a>

React 的写法

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('链接被点击');
  }
 
  return (
    <a href="#" onClick={handleClick}>
      点我
    </a>
  );
}

12.bind用法

类的方法默认是不会绑定 this 的。如果你忘记绑定 this.handleClick 并把它传入 onClick, 当你调用这个函数的时候 this 的值会是 undefined。

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
 
    // 这边绑定是必要的,这样 `this` 才能在回调函数中使用
    this.handleClick = this.handleClick.bind(this);
  }
 
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
 
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
 
ReactDOM.render(
  <Toggle />,
  document.getElementById('example')
);

13.向事件处理程序传递参数

class Popper extends React.Component{
    constructor(){
        super();
        this.state = {name:'Hello world!'};
    }
    
    preventPop(name, e){    //事件对象e要放在最后
        e.preventDefault();
        alert(name);
    }
    
    render(){
        return (
            <div>
                <p>hello</p>
                {/* 通过 bind() 方法传递参数。 */}
                <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
            </div>
        );
    }
}

14.条件渲染

React 中的条件渲染和 JavaScript 中的一致,使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI。
先来看两个组件

function UserGreeting(props) {
  return <h1>欢迎回来!</h1>;
}

function GuestGreeting(props) {
  return <h1>请先注册。</h1>;
}

创建一个 Greeting 组件,它会根据用户是否登录来显示其中之一

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}
 
ReactDOM.render(
  // 尝试修改 isLoggedIn={true}:
  <Greeting isLoggedIn={false} />,
  document.getElementById('example')
);

15.与运算符 &&

可以通过用花括号包裹代码在 JSX 中嵌入任何表达式 ,也包括 JavaScript 的逻辑与 &&,它可以方便地条件渲染一个元素

function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          您有 {unreadMessages.length} 条未读信息。
        </h2>
      }
    </div>
  );
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
  <Mailbox unreadMessages={messages} />,
  document.getElementById('example')
);

如果条件是 true,&& 右侧的元素就会被渲染,如果是 false,React 会忽略并跳过它

16.三目运算符

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

17.阻止组件渲染

在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。
让 render 方法返回 null 而不是它的渲染结果即可实现
在下面的例子中,<WarningBanner />根据属性 warn 的值条件渲染。如果 warn 的值是 false,则组件不会渲染

function WarningBanner(props) {
  if (!props.warn) {
    return null;
  }
 
  return (
    <div className="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 ? '隐藏' : '显示'}
        </button>
      </div>
    );
  }
}
 
ReactDOM.render(
  <Page />,
  document.getElementById('example')
);

组件的 render 方法返回 null 并不会影响该组件生命周期方法的回调

18.使用 JavaScript 的 map() 方法来创建列表

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((numbers) =>
  <li>{numbers}</li>
);
 
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('example')
);

19.修改state里面的属性

// Correct
this.setState({comment: 'Hello'});

20.状态更新可能是异步的

例如,此代码可能无法更新计数器

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

正确

// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));

上方代码使用了箭头函数,但它也适用于常规函数:

// Correct
this.setState(function(prevState, props) {
  return {
    counter: prevState.counter + props.increment
  };
});

21.React 事件

通过 onClick 事件来修改数据

class HelloMessage extends React.Component {
  constructor(props) {
      super(props);
      this.state = {value: 'Hello Runoob!'};
      this.handleChange = this.handleChange.bind(this);
  }
  
  handleChange(event) {
    this.setState({value: '菜鸟教程'})
  }
  render() {
    var value = this.state.value;
    return <div>
            <button onClick={this.handleChange}>点我</button>
            <h4>{value}</h4>
           </div>;
  }
}
ReactDOM.render(
  <HelloMessage />,
  document.getElementById('example')
);

React 组件生命周期

组件的生命周期可分成三个状态

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

生命周期的方法

componentWillMount

在渲染前调用

componentDidMount

在第一次渲染后调用

componentWillReceiveProps

在组件接收到一个新的 prop (更新后)时被调用。在初始化render时不会被调用。

shouldComponentUpdate

返回一个布尔值在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。

componentWillUpdate

组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用

componentDidUpdate

在组件完成更新后立即调用。在初始化时不会被调用

componentWillUnmount

在组件从 DOM 中移除之前立刻被调用

生命周期介绍

生命周期介绍

初始化调用

1、getDefaultProps()

设置默认的props,也可以用dufaultProps设置组件的默认属性.

2、getInitialState()

在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props

3、componentWillMount()

组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。

4、 render()

react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。

5、componentDidMount()

组件渲染之后调用,只调用一次。

更新

1、componentWillReceiveProps(nextProps)

组件初始化时不调用,组件接受新的props时调用。

2、shouldComponentUpdate(nextProps, nextState)

react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候

3、componentWillUpdata(nextProps, nextState)

组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state

4、render()

组件渲染

5、componentDidUpdate()

组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。

卸载

6、componentWillUnmount()

组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中

class Button extends React.Component {
  constructor(props) {
      super(props);
      this.state = {data: 0};
      this.setNewNumber = this.setNewNumber.bind(this);
  }
  
  setNewNumber() {
    this.setState({data: this.state.data + 1})
  }
  render() {
      return (
         <div>
            <button onClick = {this.setNewNumber}>INCREMENT</button>
            <Content myNumber = {this.state.data}></Content>
         </div>
      );
    }
}
 
 
class Content extends React.Component {
  componentWillMount() {
      console.log('Component WILL MOUNT!')
  }
  componentDidMount() {
       console.log('Component DID MOUNT!')
  }
  componentWillReceiveProps(newProps) {
        console.log('Component WILL RECEIVE PROPS!')
  }
  shouldComponentUpdate(newProps, newState) {
        return true;
  }
  componentWillUpdate(nextProps, nextState) {
        console.log('Component WILL UPDATE!');
  }
  componentDidUpdate(prevProps, prevState) {
        console.log('Component DID UPDATE!')
  }
  componentWillUnmount() {
         console.log('Component WILL UNMOUNT!')
  }
 
    render() {
      return (
        <div>
          <h3>{this.props.myNumber}</h3>
        </div>
      );
    }
}
ReactDOM.render(
   <div>
      <Button />
   </div>,
  document.getElementById('example')
);

React AJAX(数据请求)

React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据时可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 实例</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<div id="example"></div>

<script type="text/babel">
class UserGist extends React.Component {
  constructor(props) {
      super(props);
      this.state = {username: '', lastGistUrl: ''};
  }

 
  componentDidMount() {
    this.serverRequest = $.get(this.props.source, function (result) {
      console.log(result);
      var lastGist = result[0];
      this.setState({
        username: lastGist.owner.login,
        lastGistUrl: lastGist.html_url
      });
    }.bind(this));
  }
 
  componentWillUnmount() {
    this.serverRequest.abort();
  }
 
  render() {
    return (
      <div>
        {this.state.username} 用户最新的 Gist 共享地址:
        <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
      </div>
    );
  }
}
 
ReactDOM.render(
  <UserGist source="https://api.github.com/users/octocat/gists" />,
  document.getElementById('example')
);
</script>

</body>
</html>

补充


①Component定义和Render使用

import React from 'react';
class CommentBox extends React.Component {
    render(){
        return(
            <div className="ui comments">
                <h1>评论</h1>
                <div className="ui divider"></div>
            </div>
        ); 
    }
}
export {CommentBox as default};

第二种

class CommentList extends React.Component {
  render(){
      let commentNodes = this.props.data.map(comment =>{
        return (
          <Comment author={comment.author} date={comment.date}>
             {comment.text}
          </Comment>
        );
      })
  }
};

this.props.children表示组件的所有子节点

this.props.children的值有三种可能:

    1. 当前组件没有子节点,为 undefined
    1. 若只有一个子节点,类型为 Object
    1. 若有多个子节点,类型为 Array

通常不直接处理this.props.children,而是用React.Children.map/forEach等API来操作,
该API进行了类型处理,保证不会出错。

③加载本地json

15598096663749.jpg
15598096834817.jpg
15598106117013.jpg

[图片上传失败...(image-d44f69-1559823451981)]

④更新数据

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

推荐阅读更多精彩内容

  • 作为一个合格的开发者,不要只满足于编写了可以运行的代码。而要了解代码背后的工作原理;不要只满足于自己的程序...
    六个周阅读 8,449评论 1 33
  • 40、React 什么是React?React 是一个用于构建用户界面的框架(采用的是MVC模式):集中处理VIE...
    萌妹撒阅读 1,017评论 0 1
  • 1、什么是react React.js 是一个帮助你构建页面 UI 的库。React.js 将帮助我们将界面分成了...
    谷子多阅读 2,558评论 1 13
  • HTML模版 之后出现的React代码嵌套入模版中。 1. Hello world 这段代码将一个一级标题插入到指...
    ryanho84阅读 6,243评论 0 9
  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,840评论 1 18