app W3 reactjs 学习

1 react教程

2 react 安装

mkdir reactapp
  801  cd reactapp/
  802  npm init -y
  803  npm install --save react react-dom
  804  npm install --save-dev babel-core babel-loader babel-preset-react babel-preset-es2015 
  805  npm install --save-dev webpack
  806  touch index.html
  807  touch App.jsx
  808  touch main.js
  809  touch webpack.config.js

cat package.json

{
  "name": "reactapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.22.0",
    "webpack": "^2.2.1"
  }
}

cat webpack.config.js

var config = {
    entry: './main.js',
    output: {
        path: __dirname,
        filename: 'index.js',
    },
    devServer: {
        inline: true,
        port: 3000,
        host: '0.0.0.0',
    },
    module: {


        loaders: [{
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',

            query: {
                presets: ['es2015', 'react'],
            },
        }],
    },
};
module.exports = config;

cat index.html

<!DOCTYPE html>
<html>
 <head>
  <meta charset ="UTF-8">
  </head>
  <title> react app</title>
  <body>
    <div id="app" ></div>
    <script src ="index.js">
    </script>

</html>

cat App.jsx

import React from "react";

export default class App extends React.Component{
render(){
 return(
 <div>
  hello
 </div>
 );
}
}

cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

ReactDOM.render(<App />,
document.getElementById('app'));

这里写图片描述

3JSX

1 独立文件
cat 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>

JavaScript 表达式
我们可以在 JSX 中使用 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')
);

样式
React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:

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

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

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

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

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

6HTML 标签 vs. React 组件
React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。
要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。

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

要渲染 React 组件,只需创建一个大写字母开头的本地变量。

var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));

React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。

4 React 组件

如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello{this.props.name}</h1>;
  }
});

ReactDOM.render(<HelloMessage name="denny"/>,
document.getElementById('app'));

npm start
以上实例中 name 属性通过 this.props.name 来获取。

2复合组件
我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。
以下实例我们实现了输出网站名字和网址的组件:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';
var WebSite = React.createClass({
  render: function() {
    return (
      <div>
        <Name name={this.props.name} />
        <Link site={this.props.site} />
      </div>
    );
  }
});

var Name = React.createClass({
  render: function() {
    return (
      <h1>{this.props.name}</h1>
    );
  }
});

var Link = React.createClass({
  render: function() {
    return (
      <a href={this.props.site}>
        {this.props.site}
      </a>
    );
  }
});

ReactDOM.render(
  <WebSite name="菜鸟教程" site=" http://www.runoob.com" />,
  document.getElementById('app')
);

5 React State(状态)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
以下实例中创建了 LikeButton 组件,getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var LikeButton = React.createClass({
  getInitialState: function(){
    return {liked: false};//这里为啥不是()
  },
  handleClick:function(event){
    this.setState({liked:!this.state.liked});
  },
  render:function(){
    var text = this.state.liked?'喜欢':'不喜欢';
    return(
      <p onClick={this.handleClick}>
      你<b>{text}</b>我, 点我换状态
      </p>
    );
  }
});


ReactDOM.render(
  <LikeButton  />,
  document.getElementById('app')
);

6 React Props

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var HelloMessage = React.createClass({
  render:function(){
    return<h1> hi,{this.props.name}</h1>;
  }
});


ReactDOM.render(
  <HelloMessage name ="denny"  />,
  document.getElementById('app')
);

你可以通过 getDefaultProps() 方法为 props 设置默认值,实例如下:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var HelloMessage = React.createClass({
  getDefaultProps: function(){
    return{
      name:'denny'
    };
  },

render:function(){
  return<h1> hello,{this.props.name}</h1>;
}
});

ReactDOM.render(
  <HelloMessage  />,
  document.getElementById('app')
);

State 和 Props
以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var WebSite = React.createClass({
  getInitialState: function(){
    return {
      name:"菜",
      site:"http://www.baidu.com"
    };
  },
  render:function(){
    return(
    <div>
    <Name name={this.state.name} />
    <Link site={this.state.site} />
    </div>
  );
}
});

var Name = React.createClass({
  render: function(){
    return(
      <h1> {this.props.name}</h1>
    );
  }
});
var Link = React.createClass({
  render: function(){
    return(
      <a href ={this.props.site}>
      <h1> {this.props.site}</h1>
      </a>
    );
  }
});
ReactDOM.render(
  <WebSite  />,
  document.getElementById('app')
);

Props 验证
Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。
以下实例创建一个 Mytitle 组件,属性 title 是必须的且是字符串,如果是一个数字则会报错 :
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var title = "教程";
//var title = 123;
var MyTitle = React.createClass({
  propTypes:{
    title:React.PropTypes.string.isRequired,
  },

  render:function(){
    return<h1> {this.props.title}</h1>;
  }
});
ReactDOM.render(
  <MyTitle title={title}  />,
  document.getElementById('app')
);

7 React 组件 API

7个方法:
设置状态:setState
替换状态:replaceState
设置属性:setProps
替换属性:replaceProps
强制更新:forceUpdate
获取DOM节点:findDOMNode
判断组件挂载状态:isMounted

关于setState
不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。
setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。
setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var Counter = React.createClass({
  getInitialState:function(){
    return{clickCount:0};
  },
  handleClick:function(){
    this.setState(function(state){
      return{clickCount:state.clickCount +1};
    });
  },
  render:function(){
    return(<h2 onClick={this.handleClick}>点我,点击次数为:{this.state.clickCount}</h2>);
  }
});
ReactDOM.render(
  <Counter />,
  document.getElementById('app')
);

替换状态:replaceState

replaceState(object nextState[, function callback])
nextState,将要设置的新状态,该状态会替换当前的state。
callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。
replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。

设置属性:setProps

setProps(object nextProps[, function callback])
nextProps,将要设置的新属性,该状态会和当前的props合并
callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。
设置组件属性,并重新渲染组件。
props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()。
更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。

替换属性:replaceProps

replaceProps()方法与setProps类似,但它会删除原有props

强制更新:forceUpdate

forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。
forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()
一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。

获取DOM节点:findDOMNode

DOMElement findDOMNode()
返回值:DOM元素DOMElement
如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。

判断组件挂载状态:isMounted

bool isMounted()
返回值:true或false,表示组件是否已挂载到DOM中
isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了setState()和forceUpdate()在异步场景下的调用不会出错。

8 React 组件生命周期

组件的生命周期可分成三个状态:
Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
生命周期的方法有:
componentWillMount 在渲染前调用,在客户端也在服务端。
componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。
componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。
shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
可以在你确认不需要更新组件时使用。
componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。
这些方法的详细说明,可以参考官方文档。
以下实例在 Hello 组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒重新设置组件的透明度,并重新渲染:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var Hello = React.createClass({
  getInitialState:function(){
  return{
    opacity:1.0
  };
  },

  componentDidMount:function(){
    this.timer = setInterval(function(){
      var opacity = this.state.opacity;
      opacity -= .05;
      if(opacity<0.1){
        opacity = 1.0
      }
      this.setState({
        opacity:opacity
      });
    }.bind(this),100);
  },
  render:function(){
    return(
      <div style={{opacity:this.state.opacity}}>
      hello {this.props.name}
      </div>
    );
  }

});
ReactDOM.render(
  <Hello name="world" />,
 document.getElementById('app')
);

以下实例初始化 state , setNewnumber 用于更新 state。所有生命周期在 Content 组件中。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var Button = React.createClass({
  getInitialState:function(){
  return{
    data:0
  };
  },
 setNewNumber:function(){
   this.setState({data:this.state.data+1})
 },
  render:function(){
    return(
      <div>
      <button onClick = {this.setNewNumber}> INCREMENT</button>
      <Content myNumber = {this.state.data}></Content>
      </div>
    );
  }

});
var Content = React.createClass({
  componentWillMount:function(){
    console.log('Component will mount');
  },
  componentDidMount:function(){
    console.log('component did mount');
  },
  componentWillReceiveProps:function(newProps){
    console.log('component will receive props');
  },
  shouldComponentUpdate:function(newProps, newState) {
        return true;
  },
  componentWillUpdate:function(nextProps,nextState){
    console.log('component will update');
  },
  componentDidUpdate:function(prevProps,prevState){
    console.log('component did update');
  },
  componentWillUnmount:function(){
    console.log('component will unmount');
  },

  render:function(){
    return(
      <div>
      <h3> {this.props.myNumber}</h3>
      </div>
    );
  }
});
ReactDOM.render(
  <div>
  <Button />
  </div>,
 document.getElementById('app')
);

9 React AJAX

React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
以下实例演示了获取 Github 用户最新 gist 共享描述:
[执行不了】Uncaught ReferenceError: mountNode is not defined
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';
var UserGist = React.createClass({
  getInitialState: function() {
    return {
      username: '',
      lastGistUrl: ''
    };
  },

  componentDidMount: function() {
    this.serverRequest = $.get(this.props.source, function (result) {
      var lastGist = result[0];
      this.setState({
        username: lastGist.owner.login,
        lastGistUrl: lastGist.html_url
      });
    }.bind(this));
  },

  componentWillUnmount: function() {
    this.serverRequest.abort();
  },

  render: function() {
    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" />,
  mountNode
);

10 React 表单与事件

一个简单是实例

在实例中我们设置了输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state。我们可以使用 onChange 事件来监听 input 的变化,并修改 state。
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';
var HelloMessage = React.createClass({
  getInitialState: function() {
    return {
      value:'hello denny'
    };
  },

handleChange:function(event){
  this.setState({value:event.target.value});//这个还要好好学学
},

  render: function() {
    var value = this.state.value;
    return (
      <div>
    <input type="text" value={value} onChange={this.handleChange} />
    <h4>{value}</h4>
      </div>
    );
  }
});

ReactDOM.render(
  <div>
  <HelloMessage />
  </div>,
 document.getElementById('app')
);

上面的代码将渲染出一个值为 Hello Runoob! 的 input 元素,并通过 onChange 事件响应更新用户输入的值。

实例 2

在以下实例中我么将为大家演示如何在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。
你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。

cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var Content = React.createClass({
  render:function(){
    return(<div>
    <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp}
    />
    <h4> {this.props.myDataProp}</h4>
    </div>
  );
  }
});
var HelloMessage = React.createClass({
  getInitialState: function() {
    return {
      value:'hello denny'
    };
  },

handleChange:function(event){
  this.setState({value:event.target.value});
},

  render: function() {
    var value = this.state.value;
    return (
      <div>
    <Content myDataProp={value}
    updateStateProp = {this.handleChange}></Content>
      </div>
    );
  }
});

ReactDOM.render(
  <div>
  <HelloMessage />
  </div>,
 document.getElementById('app')
);

React 事件

以下实例演示通过 onClick 事件来修改数据:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

// var Content = React.createClass({
//   render:function(){
//     return(<div>
//     <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp}
//     />
//     <h4> {this.props.myDataProp}</h4>
//     </div>
//   );
//   }
// });
var HelloMessage = React.createClass({
  getInitialState: function() {
    return {value: 'Hello Runoob!'};
  },
  handleChange: function(event) {
    this.setState({value: '菜鸟教程'})
  },
  render: function() {
    var value = this.state.value;
    return (<div>
            <button onClick={this.handleChange}>点我</button>
            <h4>{value}</h4>
           </div>);
  }
});

ReactDOM.render(
  <div>
  <HelloMessage />
  </div>,
 document.getElementById('app')
);

当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var Content = React.createClass({
  render:function(){
    return(
      <div>
  <button onClick = {this.props.updateStateProp}>点我</button>
  <h4>{this.props.myDataProp} </h4>
    </div>
  );
  }
});
var HelloMessage = React.createClass({
  getInitialState: function() {
    return {value: 'Hello Runoob!'};
  },
  handleChange: function(event) {
    this.setState({value: '菜鸟教程'})
  },
  render: function() {
    var value = this.state.value;
    return (<div>
            <Content myDataProp ={value}
            updateStateProp ={this.handleChange}></Content>
           </div>);
  }
});

ReactDOM.render(
  <div>
  <HelloMessage />
  </div>,
 document.getElementById('app')
);

11 React Refs

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。
这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。

完整实例

你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下:
cat main.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.jsx';

var MyComponent = React.createClass({
  handleClick:function(){
    //使用原生的DOM API得到焦点
    this.refs.myInput.focus();
  },
  render:function(){
    //当组件插入到DOM后,ref属性添加一个组件的引用到this.refs
    return(
      <div>
      <input type="text" ref="myInput" />
      <input
      type="button"
      value="点我输入框获取焦点"
      onClick={this.handleClick}
      />
      </div>
    );
  }
});
ReactDOM.render(
  <div>
  <MyComponent />
  </div>,
 document.getElementById('app')
);

实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。
我们也可以使用 getDOMNode()方法获取DOM元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值