01_HelloWorld

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>01_HelloWorld</title>
</head>
<body>
<!--
1. 相关js库react.js: React的核心库react-dom.js: 提供操作DOM的扩展库babel.min.js: 解析JSX语法代码转为纯JS语法代码的库
2. 在页面中导入js<script src="../js/react.js"></script><script src="../js/react-dom.js"></script><script src="../js/babel.min.js"></script>
3. 编码<div id="example"></div><script type="text/babel"> //必须用babelReactDOM.render(<h1>Hello, React!</h1>,document.getElementById('example'));</script>
--><div id="demo"></div><script type="text/javascript" src="../js/react.js"></script>
<script type="text/javascript" src="../js/react-dom.js"></script>
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">//页面中的真实容器元素var containDiv = document.getElementById('demo');//react的虚拟DOM对象var vDom = <div id="demo">Hello, React!</div>;  //不是字符串, 不能加引号//将虚拟DOM对象渲染到页面元素中ReactDOM.render(vDom, containDiv);//页面结果: <div id="demo"><div id="demo">Hello, React!</div></div>
</script></body>
</html>

02_JSX

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>02_JSX_DEMO</title>
</head>
<body>
<ul><li>A</li><li>B</li><li>C</li>
</ul>
<hr><div id="example1"></div>
<div id="example2"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">/*功能: 动态展示列表数据*//*技术点:1). 使用JSX创建虚拟DOM2). React能自动遍历显示数组中所有的元素3). array.map()的使用*/var names = ['Tom2', 'Jack2', 'Bob2'];ReactDOM.render(<ul>{names.map(function (item, index) {return <li key={index}>{item}</li>;})}</ul>,document.getElementById('example1'));//简化编码(箭头函数)ReactDOM.render(<ul>{names.map((item, index)=><li key={index}>{item}</li>)}</ul>,document.getElementById('example2'));</script>
</body>
</html>

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>02_JSX</title>
</head>
<body>
<!--
1. 虚拟DOM1). React提供了一些API来创建一种 `特别` 的一般js对象* var element = React.createElement('h1', {id:'myTitle'}, 'hello');* 上面创建的就是一个简单的虚拟DOM对象2). 虚拟DOM对象最终都会被React转换为真实的DOM3). 我们编码时基本只需要操作react的虚拟DOM相关数据, react会转换为真实DOM变化而更新界面
2. JSX1). 全称: JavaScript XML2). react定义的一种类似于XML的JS扩展语法: XML+JS3). 作用: 用来创建react虚拟DOM(元素)对象* var ele = <h1>Hello JSX!</h1>;* 注意1: 它不是字符串, 也不是HTML/XML标签* 注意2: 它最终产生的就是一个JS对象4). 标签名任意: HTML标签或其它标签5). 标签属性任意: HTML标签属性或其它6). 基本语法规则* 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析* 遇到以 { 开头的代码,以JS的语法解析: 标签中的js代码必须用{}包含7). babel.min.js的作用* 浏览器的js引擎是不能直接解析JSX语法代码的, 需要babel转译为纯JS的代码才能运行* 只要用了JSX,都要加上type="text/babel", 声明需要babel来处理
3. 渲染虚拟DOM(元素)1). 语法: ReactDOM.render(virtualDOM, containerDOM) :2). 作用: 将虚拟DOM元素渲染到真实容器DOM中显示3). 参数说明* 参数一: 纯js或jsx创建的虚拟dom对象* 参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)
4. 创建虚拟DOM的2种方式:1). 纯JS(一般不用):React.createElement('h1', {id:'myTitle'}, title)2). JSX:<h1 id='myTitle'>{title}</h1>
-->
<div id="example1"></div>
<div id="example2"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">//初始化动态数据var title = 'I Love you!';var myName = 'xfzhang';//创建虚拟dom : JSXvar vDOM = <h1 id="myTitle" name={myName}>{title}</h1>;//将虚拟dom渲染中页面元素中ReactDOM.render(vDOM, document.getElementById('example1'));
</script><script type="text/javascript">var title = 'You Love me!';var myName = 'zhiyong';//创建虚拟dom : 纯JS(一般不用)var vDOM2 = React.createElement('h1', {id: 'myTitle2', name: myName.toUpperCase()}, title.toUpperCase());//将虚拟dom渲染中页面元素中ReactDOM.render(vDOM2, document.getElementById('example2'));
</script></body>
</html>

03_component_basic

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>03_component_basic</title>
</head>
<body><div id="example1"></div>
<div id="example2"></div>
<div id="example3"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">
/*
1. 自定义组件(Component) :1). 定义组件//方式1: 工厂(无状态)函数(最简洁, 推荐使用)function MyComponent1() {return <h1>自定义组件标题11111</h1>}//方式2: ES6类语法(复杂组件, 推荐使用)class MyComponent3 extends React.Component {render () {return <h1>自定义组件标题33333</h1>}}//方式3: ES5老语法(不推荐使用了)var MyComponent2 = React.createClass({render () {return <h1>自定义组件标题22222</h1>}})2). 渲染组件标签ReactDOM.render(<MyComponent/>, document.getElementById('example'));
2. 注意:1). 返回的组件类必须首字母大写2). 虚拟DOM元素必须只有一个根元素3). 虚拟DOM元素必须有结束标签
3. ReactDOM.render()渲染组件标签的基本流程1). React内部会创建组件实例对象2). 得到包含的虚拟DOM并解析为真实DOM3). 插入到指定的页面元素内部
*///1. 定义组件//方式1: 工厂(无状态)函数(简单组件, 推荐使用)function MyComponent1() {return <h1>工厂(无状态)函数--->自定义组件标题11111</h1>;}//方式2: ES6类语法(复杂组件, 推荐使用)class MyComponent2 extends React.Component {render() {console.log(this, this instanceof MyComponent3);return <h1>ES6类语法--->自定义组件标题22222</h1>;}}//方式3: ES5老语法(不推荐使用了)var MyComponent3 = React.createClass({render() {return <h1>ES5老语法--->自定义组件标题3333</h1>;}});console.log(typeof MyComponent3);/************************************************************************///2. 渲染组件标签ReactDOM.render(<MyComponent1/>, document.getElementById('example1'));ReactDOM.render(<MyComponent2/>, document.getElementById('example2'));ReactDOM.render(<MyComponent3/>, document.getElementById('example3'));
</script>
</body>
</html>

04_component_props

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>04_component_props</title>
</head>
<body><ul><li>姓名: 张三</li><li>性别: 女</li><li>年龄: 23</li>
</ul>
<hr><div id="example"></div>
<div id="example2"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">/*组件实对象3大属性之一: props属性1. 每个组件对象都会有props(properties的简写)属性2. 组件标签的所有属性都保存在props中3. 内部读取某个属性值: this.props.propertyName4. 作用: 通过标签属性从组件外向组件内传递数据(只读)5. 对props中的属性值进行类型限制和必要性限制Person.propTypes = {name: React.PropTypes.string.isRequired,age: React.PropTypes.number.isRequired}6. 扩展属性: 将对象的所有属性通过props传递<Person {...person}/>7. 默认属性值Person.defaultProps = {name: 'Mary'};8. 组件类的构造函数constructor (props) {super(props);console.log(props); // 查看所有属性}问题: 为什么要设计对prop会进行约束的语法?*//*需求: 自定义用来显示一个人员信息的组件, 效果如页面. 说明1). 如果性别没有指定, 默认为男2). 如果年龄没有指定, 默认为18*/class Person extends React.Component {constructor(props) {super(props);console.log(props); //查看所有属性}render() {return (<ul><li>姓名: {this.props.name}</li><li>性别: {this.props.sex}</li><li>年龄: {this.props.age}</li></ul>);}}Person.propTypes = {name: React.PropTypes.string.isRequired,sex: React.PropTypes.string.isRequired,age: React.PropTypes.number.isRequired};Person.defaultProps = {sex: '男',age: 18};/************************************************************************///初始化数据let person = {name: 'qicaiyun', sex: '女', age: 3};// person = { name: 'qicaiyun', sex: '女', age: "3" }; // 会抛出警告age不是number类型的//根据数据动态渲染组件标签/*ReactDOM.render(<Person name={person.name} age={person.age} sex={person.sex}/>,document.getElementById('example'));*/ReactDOM.render(<Person {...person}/>,document.getElementById('example'));const person2 = {name: 'kobe', sex: '女'};ReactDOM.render(<Person {...person2}/>, document.getElementById('example2'));
</script>
</body>
</html>

05_components_composing

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>05_components_composing</title>
</head>
<body>
<div><h2>Welcome A!</h2><h2>Welcome B!</h2><h2>Welcome C!</h2>
</div>
<hr><div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">/*1. 拆分组件: 拆分界面, 抽取组件* 单个标题组件: Welcome* 应用组件: App2. 分析确定传递数据和数据类型* Welcome: props.name  string* App: props.names    array*///定义内部标题组件class Welcome extends React.Component {render() {return <h2>Welcome {this.props.name}!</h2>;}}Welcome.propTypes = {name: React.PropTypes.string.isRequired};//定义外部应用组件class App extends React.Component {render() {return (<div>{this.props.names.map((name, index) => <Welcome name={name} key={index}/>)}</div>);}}App.propTypes = {names: React.PropTypes.array.isRequired};/**********************************************************/var names = ['Tom', 'Jack', "Bob"];ReactDOM.render(<App names={names}/>, document.getElementById('example'));
</script>
</body>
</html>

06_component_refs_event

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>07_component_refs</title>
</head>
<body><input type="text"><button>提示输入数据</button><input type="text" placeholder="失去焦点提示数据"><hr><div id="example"></div><script src="../js/react.js"></script><script src="../js/react-dom.js"></script><script src="../js/babel.min.js"></script><script type="text/babel">/*
1. 组件实例对象的3大属性之二: refs属性1). 组件内的标签都可以定义ref属性来标识自己2). 在组件中可以通过this.refs.refName来得到对应的真实DOM对象3). 作用: 用于操作指定的ref属性的dom元素对象(表单标签居多)* <input ref='username' />* this.refs.username //返回input对象
2. 事件处理1). 通过onXxx属性指定组件的事件处理函数(注意大小写)* React使用的是自定义(合成)事件, 而不是使用的DOM事件* React中的事件是通过委托方式处理的(委托给组件最外层的元素)2). 通过event.target得到发生事件的DOM元素对象<input onFocus={this.handleClick}/>handleFocus(event) {event.target  //返回input对象}
3. 强烈注意1). 组件内置的方法中的this为组件对象2). 在组件中自定义的方法中的this为null* 强制绑定this* 箭头函数(ES6模块化编码时才能使用)
4. 问题: 如何给一个函数强制指定内部的this?*//*需求: 自定义组件, 功能说明如下:1. 界面如果页面所示2. 点击按钮, 提示第一个输入框中的值3. 当第2个输入框失去焦点时, 提示这个输入框中的值*/class RefsTest extends React.Component {constructor (props) {super(props);this.showMsg = this.showMsg.bind(this); // 强制给showMsg()绑定this(组件对象)this.handleBlur = this.handleBlur.bind(this);}showMsg() {// console.log(this); //this默认是null, 而不组件对象const input = this.refs.msg;alert(input.value);}handleBlur(event) {const input = event.target;alert(input.value);}render () {return (<div><input type="text" ref="msg"/><button onClick={this.showMsg}>提示输入数据</button><input type="text" placeholder="失去焦点提示数据" onBlur={this.handleBlur}/></div>);}}ReactDOM.render(<RefsTest/>, document.getElementById('example'));</script>
</body>
</html>

07_component_state

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>07_component_state</title>
</head>
<body><div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*组件实例对象3大属性之: state属性1). 组件被称为"状态机", 通过更新组件的状态值来更新对应的页面显示(重新渲染)2). 初始化状态:constructor (props) {super(props)this.state = {stateProp1 : value1,stateProp2 : value2}}3). 读取某个状态值this.state.statePropertyName4). 更新状态---->组件界面更新this.setState({stateProp1 : value1,stateProp2 : value2})5). 问题: 请区别一下组件的props和state属性?*//*需求: 自定义组件, 功能说明如下1. 显示h2标题, 初始文本为: 你喜欢我2. 点击标题更新为: 我喜欢你*/class LikeMe extends React.Component {constructor(props) {super(props)this.state = {isLikeMe: false}this.switchLikeMe = this.switchLikeMe.bind(this)}switchLikeMe() {let isLikeMe = !this.state.isLikeMe;this.setState({isLikeMe})}render() {let text = this.state.isLikeMe ? '你喜欢我' : '我喜欢你'return <h2 onClick={this.switchLikeMe}>{text}</h2>}}ReactDOM.render(<LikeMe/>, document.getElementById('example'))</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>07_state_demo</title>
</head>
<body>
<div><h2>Simple TODO List</h2><input type="text"><button>Add #4</button><ul><li>吃饭</li><li>睡觉</li><li>打豆豆</li></ul>
</div>
<hr><div id="example">在此实现页面效果和功能</div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*功能: 组件化实现此功能1. 界面显示如上所示2. 输入文本, 点击按钮显示到下面列表的首位, 并清除输入的文本*//*分解组件:列表: TodoListprops: todos应用: Appstate: todos, inputTodo*//*问题: 完善功能1). 如果没有输入或输入的只是空格, 不添加到列表2). 如果输入的文本两边有空格, 去掉空格后添加*//**  拆分组件:*  1、添加 todo的组件  AddTodo*  2、显示todo列表: TodoList*  3、 应用主组件: App** *///定义AddTodo组件class AddTodo extends React.Component{constructor(props){super(props);this.add = this.add.bind(this);}add(){//获取输入的值let value = this.refs.newTodo.value;//console.log(typeof value);//判断输入的内容是否为空格if(!value.trim()){return}//将输入的值添加到 todoList中//console.log(value);this.props.add(value);this.refs.newTodo.value = '';}render(){return (<div><input ref="newTodo" type="text" /><button onClick={this.add}>Add #{this.props.length}</button></div>)}}//定义 TodoList 组件class TodoList extends React.Component{render(){let {todoList} = this.props;return (<ul>{todoList.map(function (item, index) {return <li key={index}>{item}</li>})}</ul>)}}class App extends React.Component{constructor(props){super(props);this.state = {todoList : ['吃饭', '睡觉', '打豆豆', '学习']};this.add = this.add.bind(this);}add(newTodo){console.log(newTodo);let todoList = this.state.todoList;todoList.unshift(newTodo);this.setState({todoList})}render(){let {todoList} = this.state;return (<div><h2>Simple TODO List</h2><AddTodo add={this.add} length={this.state.todoList.length}/><TodoList todoList={todoList}/></div>)}}//渲染组件ReactDOM.render(<App />, document.getElementById('example'));</script>
</body>
</html>

08_component_controlled

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>09_form</title>
</head>
<body><input type="text" value="qicaiyun">
<p>qicaiyun</p><hr><div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*受控组件1. React是一个单向数据流2. 但可以自定义双向数据流组件(受控组件)*//*功能: 自定义组件, 功能如下1. 界面如页面所示2. 初始数据显示为qicaiyun3. 输入数据时, 下面的数据同步变化*/class TwoWay extends React.Component {constructor(props) {super(props)this.state = {msg: 'qicaiyun'}this.handleChange = this.handleChange.bind(this)}handleChange(event) {let msg = event.target.valuethis.setState({msg})}render() {return (<div><input type="text" value={this.state.msg} onChange={this.handleChange}/><p>{this.state.msg}</p></div>)}}ReactDOM.render(<TwoWay/>, document.getElementById('example'))
</script>
</body>
</html>

09_component_lifecycle

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>10_ComponentLife</title>
</head>
<body><div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*
1. 组件的三个生命周期状态:* Mount:插入真实 DOM* Update:被重新渲染* Unmount:被移出真实 DOM
2. React 为每个状态都提供了两种勾子(hook)函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用* componentWillMount()* componentDidMount() : 已插入真实DOM, 在render之后才会执行* componentWillUpdate(object nextProps, object nextState)* componentDidUpdate(object prevProps, object prevState)* componentWillUnmount()
3. 生命周期流程:1). 第一次初始化渲染显示: render()* constructor(): 创建对象初始化state* componentWillMount() : 将要插入回调* render() : 用于插入虚拟DOM回调* componentDidMount() : 已经插入回调2). 每次更新state: this.setSate()* componentWillUpdate() : 将要更新回调* render() : 更新(重新渲染)* componentDidUpdate() : 已经更新回调3). 删除组件* ReactDOM.unmountComponentAtNode(document.getElementById('example')) : 移除组件* componentWillUnmount() : 组件将要被移除回调
4.注意:* 一般会在componentDidMount()中: 开启监听, 发送ajax请求* 可以在componentWillUnmount()做一些收尾工作: 停止监听* 生命周期还有一个方法(后面需要时讲): componentWillReceiveProps*/class LifeCycle extends React.Component {constructor(props) {super(props);console.log('constructor(): 创建组件对象');this.state = {date: new Date().toLocaleString()};}componentWillMount() {console.log('componentWillMount(): 将要初始挂载');}componentDidMount() {console.log('componentDidMount(): 已经初始挂载');this.intervalId = setInterval(() => {this.setState({date: new Date().toLocaleString()});},1000);}componentWillUpdate() {console.log('componentWillUpdate(): 将要进行state更新');}componentDidUpdate() {console.log('componentDidUpdate(): 已经更新');}componentWillUnmount() {console.log('componentWillUnmount(): 将要被移除');clearInterval(this.intervalId);}removeComp() {ReactDOM.unmountComponentAtNode(document.getElementById('example'));}render() {console.log('render(): 渲染内部虚拟DOM');return (<div><h2>{this.props.name}, 当前时间: {this.state.date}</h2><button onClick={this.removeComp}>移除组件</button></div>);}}ReactDOM.render(<LifeCycle name="JACK"/>, document.getElementById('example'));
</script>
</body>
</html>

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>10_ComponentLife</title>
</head>
<body>
<div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*自定义组件:功能描述: 让指定的文本做显示/隐藏的动画*/class AnimateMsg extends React.Component {constructor(props) {super(props)this.state = {opacity: 1.0}}componentDidMount() {this.intervalId = setInterval(function () {var opacity = this.state.opacity;opacity -= 0.05;if (opacity < 0.05) {opacity = 1.0;}this.setState({opacity: opacity});}.bind(this), 100);}componentWillUnmount() {clearInterval(this.intervalId)}render () {return (<p style={{opacity: this.state.opacity}}>{this.props.msg}</p>);}}AnimateMsg.propTypes = {msg: React.PropTypes.string.isRequired,}ReactDOM.render(<AnimateMsg msg="www.qicaiyun.com"/>, document.getElementById('example'));
</script>
</body>
</html>

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>04_component</title>
</head>
<body>
<div id="example"></div>
<br><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">/*验证:虚拟DOM+DOM Diff算法: 最小化页面重绘*/class HelloWorld extends React.Component {constructor(props) {super(props);this.state = {date: new Date()};}componentDidMount () {setInterval(() => {this.setState({date: new Date()})}, 1000)}render () {console.log('render()')return (<p>Hello, <input type="text" placeholder="Your name here"/>!It is {this.state.date.toTimeString()}</p>);}}ReactDOM.render(<HelloWorld/>,document.getElementById('example'));
</script>
</body>
</html>

10_ajax

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>11_ajax</title>
</head>
<body>
<div id="example"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script src="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script>
<script src="//cdn.bootcss.com/fetch/2.0.1/fetch.min.js"></script>
<script type="text/babel">/*
1. React没有ajax模块* 集成其它的js库(如jQuery/fetch/axios), 发送ajax请求
2. 使用axios* https://github.com/mzabriskie/axios
3. 使用fetch:* https://github.github.io/fetch/* https://segmentfault.com/a/1190000003810652
4. 测试url:* https://api.github.com/users/octocat/gists
*/class UserGist extends React.Component {constructor(props) {super(props);this.state = {lastGistUrl: null};}componentDidMount() {const url = `https://api.github.com/users/${this.props.name}/gists`axios.get(url).then((response) => {console.log(response.data)var data = response.data;var lastGist = data[0];this.setState({lastGistUrl: lastGist.html_url});}).catch((error) => {console.log(error.response.data);});/*fetch(url).then((response) => {response.json().then((result) => {console.log(result);var lastGist = result[0];this.setState({lastGistUrl: lastGist.html_url});})},(error) => {console.log(error);});*/}render() {if(this.state.lastGistUrl===null) {return <h2>loading...</h2>} else {return (<div>{this.props.name}'s last gist is <a href={this.state.lastGistUrl}>here</a></div>);}}}var name = 'octocat'ReactDOM.render(<UserGist name={name}/>, document.getElementById('example'));
</script>
</body>
</html>

11_react-server

React服务器端渲染入门

  • 理解

    • 当服务器端接收到请求时, 在服务器端基于React动态渲染页面, 并返回给浏览器显示
    • 相对于浏览器端渲染的好处?
      • 服务器端和客户端可以共享某些代码,避免重复定义。
      • 首次加载页面的速度加快
      • 便于SEO优化。服务器端渲染可以让搜索引擎更容易读取页面的meta信息以及其他SEO相关信息
    • 相对于浏览器端渲染的不好?
      • 对服务器的压力增大
      • 要求服务器使用基于node搭建
  • 简单编码实现服务器端渲染
    • 应用文件结构

      react-node|-- src|-- App.js-----------------主组件js|-- server.js--------------启动服务器监听, 处理请求的js|-- index.js---------入口js|-- .babelrc---------babel配置文件|-- package.json-----应用包信息文件
      
    • 编码
      • package.json

        {"name": "react-node","version": "1.0.0","scripts": {"start": "node index"},"devDependencies": {"babel-preset-es2015": "^6.6.0","babel-preset-react": "^6.5.0","babel-register": "^6.8.0"},"dependencies": {"react": "^15.3.1","react-dom": "^15.3.1"}
        }
        
      • .babelrc
        {"presets": ["react", "es2015"]
        }
        
      • App.js
        import React, {Component} from 'react'
        class App extends Component {render() {return (<div>测试React服务器</div>)}
        }
        export default App
        
      • server.js
        import React from 'react';
        import { renderToString } from 'react-dom/server';
        var http = require('http');
        import App from './App';//创建服务器对象, 并启动监听
        http.createServer(function (request, response) {//向浏览器端写头信息response.writeHead(200, {'Content-Type': 'text/html'});//渲染组件成标签结构字符串const appHTML = renderToString(<App />);//向浏览器返回结果response.end(appHTML);
        }).listen(8888);
        // 终端打印提示信息
        console.log('Server running at http://127.0.0.1:8888/');
        
      • index.js
        require('babel-register');
        require('./src/server.js');
        
    • 启动服务器运行:
      • 命令: npm start
      • 访问: http://127.0.0.1:8888

12_key

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Lists and Keys</title>
</head>
<body><div id="root"></div><script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script><script type="text/babel">/*为什么列表的key尽量不要用indexhttp://jsbin.com/wohima/edit?js,outputhttp://taobaofed.org/blog/2016/08/24/react-key/?utm_source=tuicool&utm_medium=referral简单来说: 当数组中的数据发生变化时: React 比较更新前后的元素 key 值,如果相同则更新,如果不同则销毁之前的,重新创建一个元素*/function ListItem({id, name, age}) {return <li>{id}--{name}--{age}---<input type="text"/></li>;}class PersonList extends React.Component {constructor(props) {super(props);this.state = {persons: [{id: 1, name: 'Tom', age: 12},{id: 2, name: 'Jack', age: 13}]};this.update = this.update.bind(this);}update() {let persons = this.state.persons;persons.unshift({id: 3, name: 'Bob', age: 14})this.setState({persons})}render() {const persons = this.state.persons;const listItems = persons.map((person, index) =><ListItem key={person.id} {...person}/>);const listItems2 = persons.map((person, index) =><ListItem key={index} {...person}/>);return (<div><h2>使用id作为key</h2><ul>{listItems}</ul><h2>使用index作为key</h2><ul>{listItems2}</ul><button onClick={this.update}>首位添加一个人</button></div>);}}ReactDOM.render(<PersonList/>,document.getElementById('root'));
</script>
</body>
</html>

react.js学习笔记02相关推荐

  1. Vue.js学习笔记 02、Vue组件篇笔记

    文章目录 前言 一.全局组件 子组件应用 组件优点:组件的可复用性 全局组件缺点描述 二.局部组件 创建与注册局部组件(认识components属性) 局部组件的默认规定(组件名称首字母全都大写) 三 ...

  2. RN学习笔记02:利用WebStorm创建RN项目

    RN学习笔记02:利用WebStorm创建RN项目 在RN学习笔记01里,安装了node.js与react-native-cli,而且配置了环境变量. 在命令行环境,利用react-native in ...

  3. React系统学习笔记

    ***当前阶段的笔记 *** 「面向实习生阶段」https://www.aliyundrive.com/s/VTME123M4T9 提取码: 8s6v 点击链接保存,或者复制本段内容,打开「阿里云盘」 ...

  4. React.js入门笔记

    # React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...

  5. JavaWeb-综合案例(用户信息)-学习笔记02【登录功能】

    Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb-综合案例(用户信息)-学习笔记01[列表查询] JavaWeb-综合案例(用户信息)-学习笔记02[登录功能] JavaWeb-综合案 ...

  6. Tomcat学习笔记02【Tomcat部署项目】

    Java后端 学习路线 笔记汇总表[黑马程序员] Tomcat学习笔记01[Web相关概念.Tomcat基本操作][day01] Tomcat学习笔记02[Tomcat部署项目][day01] 目录 ...

  7. Bootstrap学习笔记02【全局CSS样式、组件和插件、案例_黑马旅游网_首页】

    Java后端 学习路线 笔记汇总表[黑马程序员] Bootstrap学习笔记01[快速入门.栅格布局][day01] Bootstrap学习笔记02[全局CSS样式.组件和插件.案例_黑马旅游网][d ...

  8. JavaScript学习笔记02【基础——对象(Function、Array、Date、Math)】

    w3school 在线教程:https://www.w3school.com.cn JavaScript学习笔记01[基础--简介.基础语法.运算符.特殊语法.流程控制语句][day01] JavaS ...

  9. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  10. ArcGIS JS 学习笔记4 实现地图联动

    原文:ArcGIS JS 学习笔记4 实现地图联动 1.开篇 守望屁股实在太好玩了,所以最近有点懒,这次就先写个简单的来凑一下数.这次我的模仿目标是天地图的地图联动. 天地的地图联动不仅地图有联动,而 ...

最新文章

  1. 如果我的实验室也这样布置,那多好。
  2. ajax 页面无刷新
  3. SQL调优:带函数的谓词导致CBO Cardinality计算误差
  4. 张高兴的 .NET Core IoT 入门指南:(五)串口通信入门
  5. for、foreach、stream 哪家的效率更高,你真的用对了吗?
  6. 多家大厂的存储设备受第三方加密软件缺陷影响
  7. 北方民族大学计算机考研专业课,2021北方民族大学专业课考研真题资料汇总!!...
  8. 量子计算(六):量子计算软件介绍
  9. 仓储系统货位优化毕业论文【Flexsim仿真】
  10. Black-Scholes-Merton欧式期权定价公式
  11. 硬盘安装Win7全攻略(图解)
  12. java将bmp文件转为jpg_在PHP中将BMP转换为JPG
  13. 全机房最蒟蒻的讲堂_第一期_关于orz
  14. Python-练习 43. 面向对象的分析和设计基础
  15. 华为鸿蒙系统是emui11,华为鸿蒙2.0还原EMUI11系统
  16. iPad2通过DFU模式刷机
  17. debug - UITextField 输入完跳入下一field,按钮变化
  18. 算法很美:01背包问题(动态规划、贪心)
  19. 炎黄传媒人事大变 投资方查账上现金引发恐慌
  20. 《比特彗星-教程》(编辑于2023.02.08)

热门文章

  1. 使用gentoo做构建嵌入式linux时遇到的问题两则[原]
  2. VMware Workstation下减小ubuntu系统占用系统盘大小
  3. 第三季-第2课-GDB程序调试
  4. UITableViewController与UIViewController中使用UITableView
  5. 多线程下不反复读取SQL Server 表的数据
  6. mysql cluster集群安装全纪录
  7. eclipse git 上传工程 提交项目到 github
  8. 游戏服务器当中的唯一名设计方法
  9. highcharts:根据Y的数值范围,动态改变图形的填充颜色
  10. a中嵌套div的问题