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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

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

友情链接更多精彩内容