介绍与准备
创建React项目
创建 React 项目,你需要安装很多东西,React 本身,还有一些必要的工具,比如编译 JavaScript 用的 Babel,打包用的 webpack ..
create-react-app 这个小工具可以为我们准备好创建 React 项目需要的所有的资源 … 先确定你的电脑上已经安装好了 node 还有 npm ..
然后用 npm 去安装一下 create-react-app ..
npm install -g create-react-app
然后再用它去创建一个 react 项目 … 先进入到你想要保存项目的地方 .. 比如我的桌面 .. create-react-app 后面加上项目的名字 ..
create-react-app my-app
这个工具会自动给我们下载需要的资源 ..
完成以后进入到创建好的这个项目的目录的下面 …
cd my-app
再执行一下
npm start
这个命令可以启动创建好的 react 项目 … 然后自动会在浏览器上打开创建好的这个项目 … 现在你看到的就是一个简单的 React 项目 ..
React介绍
React 是一个创建显示组件的东西, 创建好组件以后,他们就会按照你设计的去显示,当组件上的数据有变化的时候,它们会用一种非常有效率的方法自动更新变化 ..
React应用的结构
node_modules 这里存储的就是项目依赖的一些东西 .. react 本身 .. webpack .. babel,还有它们依赖的一些其它的东西 … 项目的依赖在 package.json 这个文件里说清楚了 ..
开发依赖这里,只有一个 react-scripts ,在这个包里会说清楚 react 项目需要的所有的工具 ..
dependencies 是项目的依赖 .. 这里有 react … 还有 react-dom …
这个项目的下面,有个 public 目录,一般公开的资源都会放在这个目录的下面 .. 现在这里有个 favicon.ico … 还有一个 index.html ..
src 表示 source ,应用的源 ..
index.js 是应用的入口文件 … 文档的头部先导入了一些东西 … 比如React,ReactDOM … 这些是一般的 React 项目必须要用的一些东西 ..
下面的 App 是定义好的一个 React 组件 … 然后还导入了一个 css 文件 …
在下面又用了 ReactDOM 的 render 方法,显示了一个组件 … 就是在上面导入进来的 App 组件 …
再打开这个 App.js
在这个文件里定义了一个叫 App 的组件 … 这个组件在浏览器上显示的这些东西 ..
文件的一开始,导入进来两个东西,一个是 React,还有一个 Component ,定义 React 组件需要用到这个 Component ..
下面导入进来一个 logo.svg … 它就是这里的这个 React 标志 …
在它的下面,又导入进来一个 css 文件 .. 在这个文件里定义了组件里面需要用到的一些 css 样式 …
继续再看这个 App.js
一个 React 组件可以是一个类 .. 这个类继承了 React 里面的 Component …
在这个类里,用了一下 render 方法 … 它返回了组件里要显示的一些东西 ..
这里你会看到一些像 html 的东西,但是又有点区别,比如在 html 的上面,添加 css 类,用的是 class,这里用的是 className … 因为这些并不是 html .. 是一种特别的格式,叫 JSX .. React 会把它们转换成正常的 JavaScript …
文件的最后,导出来上面定义的这个 React 组件 … 这样你就可以在其它的地方,导入并且使用这个 React 组件了 ..
编译生产环境的React应用
npm run build
编译好的应用会放在项目的 build 目录的下面 ..
static 里面是应用需要的 css,js 还有一些媒体文件 ..
我们也可以在本地运行编译好的应用 ..
先安装一下 pushstate-server ..
npm install -g pushstate-server
再执行一下
pushstate-server build
然后在浏览器上打开 localhost:9000
这里显示的就是为生产环境编译好的 React 应用 …
组件
定义组件-Component
React 可以让我们把要显示的东西分割成不同的组件,然后可以再把这些组件组合到一块儿去用。
import React from 'react';//导入 react 模块 .. 导入进来可以叫它 React ..
//定义的组件可以是一个类,先用一个 class .. 然后是组件的名字 .. CommentBox .. 让它去继承 React 的 Component ..
class CommentBox extends React.Component{
//render() 方法,在这里去定义组件要显示的东西,返回的就是要显示的东西
render(){
//在这个 return 的后面添加一组括号 .. 这样你可以在多行去定义要显示的东西
return(
//这些要显示的东西可以直接使用类似 html 的形式 .. 一般这些属性跟在普通的 html 上是一样的
//因为 class 是 javascript 保留的关键词 .. 所以这里我们可以用一个 className 来表示在 html 上的 class
<div className="ui comments">
<h1>评论</h1>
<div className="ui divider"/>
</div>
//. 这里我们定义的要显示的东西用的是 jsx 的格式 .. 它会被转换成普通的 javascript
);
}
}
//在文件的底部可以把它作为这个模块默认的东西导出来 .. 这样在其它的地方我们可以导入这个组件的功能 ..
export { CommentBox as default }
显示-ReactDOM-render
使用semantic ui的样式
cnpm install semantic-ui-react --save-dev
cnpm install semantic-ui-css --save
修改一下index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import 'semantic-ui-css/semantic.min.css';
import CommentBox from './comment/CommentBox';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<CommentBox />, document.getElementById('root'));
registerServiceWorker();
修改一下index.html
<div class="ui container" style="padding:30px">
<div id="root"></div>
</div>
组合组件
CommentBox.js
import React from 'react';
import CommentList from './CommentList';
import CommentForm from './CommentForm';
class CommentBox extends React.Component{
render(){
return(
<div className="ui comments">
<h1>评论</h1>
<div className="ui divider"/>
<CommentList/>
<CommentForm/>
</div>
);
}
}
export { CommentBox as default }
CommentForm.js
import React from 'react';
class CommentForm extends React.Component{
render(){
return(
<form action="" className="ui reply form">
<div className="field">
<input type="text" placeholder="姓名"/>
</div>
<div className="field">
<textarea name="" id="" cols="30" rows="10" placeholder="评论"/>
</div>
<button type="submit" className="ui blue button">
添加评论
</button>
</form>
);
}
}
export { CommentForm as default }
CommentList.js
import React from 'react';
class CommentList extends React.Component{
render(){
return(
<div className="ui comments">
评论列表
</div>
);
}
}
export { CommentList as default }
属性
属性-props
React元素都只是DOM标签:
const element = <div />;
React元素也可以是用户自定义的组件:
const element = <Welcome name="Sara" />;
当React遇到的元素是用户自定义的组件,它会将JSX属性作为单个对象传递给该组件,这个对象称之为“props”。
父组件向子组件传值:jsx属性
子组件接收数据:this.props
新增Comment.js
import React from 'react';
class Comment extends React.Component {
formatDate = (date) => {
return date.toLocaleDateString();
}
render() {
return (
<div className="comment">
<a className="avatar">
<img src={
this.props.author.avatarUrl} alt={
this.props.author.name}/>
</a>
<div className="content">
<a className="author">{
this.props.author.name}</a>
<div className="metadata">
<span className="date">{
this.formatDate(this.props.date)}</span>
</div>
<div className="text">{
this.props.text}</div>
<div className="actions">
<a className="reply">Reply</a>
</div>
</div>
</div>
);
}
}
export {Comment as default}
在CommentList里面使用这个组件,那么CommentList就是父组件,Comment就是子组件
import React from 'react';
import Comment from './Comment';
const comment1={
date:new Date(),
text:'天气真好',
author:{
name:'宝宝',
avatarUrl:'http://placekitten.com/g/64/64'
}
}
const comment2={
date:new Date(),
text:'出去玩呀',
author:{
name:'小小',
avatarUrl:'http://placekitten.com/g/61/61'
}
}
class CommentList extends React.Component{
render(){
return(
<div className="ui comments">
<Comment
date={comment1.date}
text={comment1.text}
author={comment1.author}/>
<Comment
date={comment2.date}
text={comment2.text}
author={comment2.author}/>
</div>
);
}
}
export { CommentList as default }
从爸爸那里得到数据
组件的数据 .. 这些数据一般应该是来自服务端 .. 你可以通过一些方法向服务端去请求数据 ..
先模拟一下
在index.js定义一个表示评论数据的变量 .. 名字是 comments .它的值是一个 json 格式的数据或者js对象,在这个 render 方法里,把这个数据传递给 CommentBox 组件 .. 添加一个 data 属性 .. 这样你可以在 CommentBox 里,得到 data 这个属性的值
key值:因为后面处理数据时候,要当成数组遍历
Each child in an array or iterator should have a unique “key” prop.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import 'semantic-ui-css/semantic.min.css';
import CommentBox from './comment/CommentBox';
import registerServiceWorker from './registerServiceWorker';
// var comments = [
// {
// "key":"1",
// "date": new Date(),
// "text": "天气真好",
// "author": {
// "name": "小小",
// "avatarUrl": "http://placekitten.com/g/61/61"
// }
// },
// {
// "key":"2",
// "date": new Date(),
// "text": "出去玩呀",
// "author": {
// "name": "宝宝",
// "avatarUrl": "http://placekitten.com/g/64/64"
// }
// }
//
// ]
var comments = [
{
key:'1',
date: new Date(),
text: '天气真好',
author: {
name: '小小',
avatarUrl: 'http://placekitten.com/g/61/61'
}
},
{
key:'2',
date: new Date(),
text: '出去玩呀',
author: {
name: '宝宝',
avatarUrl: 'http://placekitten.com/g/63/61'
}
}
]
ReactDOM.render(<CommentBox data={comments} />, document.getElementById('root'));
registerServiceWorker();
在 CommentBox 这个组件 .. 它里面嵌入了 CommentList 这个组件 ,在 render 方法用 this.props.data 获取传递过来的数据,再交给 CommentList 这个组件
import React from 'react';
import CommentList from './CommentList';
import CommentForm from './CommentForm';
class CommentBox extends React.Component{
render(){
return(
<div className="ui comments">
<h1>评论</h1>
<div className="ui divider"/>
<CommentList data={
this.props.data}/>
<CommentForm />
</div>
);
}
}
export { CommentBox as default }
CommentList .. 我们再改造一下它的 render 方法 .. 可以循环的去处理一下传递过来的数据
import React from 'react';
import Comment from './Comment';
class CommentList extends React.Component{
render(){
let commentNodes = this.props.data.map( comment => {
return (
<Comment
key={comment.key}
date={comment.date}
text={comment.text}
author={comment.author}/>
);
});
return(
<div>
{commentNodes}
</div>
);
}
}
export { CommentList as default }