# react-demo-before-conference
**Repository Path**: finalclassic/react-demo-before-conference
## Basic Information
- **Project Name**: react-demo-before-conference
- **Description**: demo before conference
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: demo
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-12-21
- **Last Updated**: 2021-12-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: training
## README
# React 入门,based on React.16.4.2
react 官网:https://reactjs.org/
本次教程基于环境、使用工具以及版本:
- nodejs:8.11.3
- react:16.4.2
- npm:6.2.0
- SPA(单页应用)
[toc]
# 1. 创建项目
## 1.1 - 安装脚手架create-react-app
```javascript
npm install -g create-react-app@2.0.0-next.3e165448
```
## 1.2 - 创建项目
```javascript
create-react-app react-demo
```
## 1.3 - 运行项目
```javascript
npm start
或者
yarn start
```
# 2. 项目结构说明
创建好项目之后的结构目录:

其中:
- /public/index.html是整个项目的入口文件,我们可以在该文件中添加一些CDN资源,如jQuery等。
index.html文件内容:

P.S.:
- 在index.html中,有一个根容器:id="root"
- 这个是整个项目的总容器,创建的组件最终都生成在该容器中。
- 对于该文件,一般情况下,我们不会在这个html文件中增加我们的业务代码
- src/index.js:跟index.html相关联,会将该js中声明的组件渲染到public/index.html中 "id=root" 的容器内

- ReactDOM.render是react最基本的方法,用于将模板转换为HTML语言,并插入到指定的DOM节点。
- 像上面的代码的意思就是把App这个组件转换成html后插入到root节点中。
- 在这里,可以将 认为是整个项目的根组件,要使用App组件,需要引入该组件,见L4(第四行)
- 通过 import App from './App' 进行引用,默认情况下,webpack自动将文件作为js文件进行处理,所以这里在引入App.js的时候,不用显式指明 "./App.js"
> 为什么从项目结构中并看不出任何跟webpack相关的文件?
# 3. 项目解包
```javascript
npm run eject
```
项目解包后的入口文件、入口函数图示:

- 解包之后的项目无法通过 npm start 这样的命令直接启动项目(解包的同时会从node_modules中删除包)
- 此时需要运行 npm install 进行安装package.json中定义的包。
# 4. JSX语法
>脚手架创建的react项目中的App.js,默认使用了JSX语法
- 使用JSX语法需要导入 react
- JSX语法与非JSX语法的对比:

## Demo
**Demo1 - 在JSX中,通过花括号 {} ,可以使用javascript表达式,如:**
```javascript
render() {
return (
hello react.
1+1={1 + 1} //最终结果:1+1=2
);
}
```
**Demo2 - JSX中无法使用 if-else,但可以使用三元表达式来代替,如:**
```javascript
render() {
let isDisplayOne = true;
let one = "i am One";
let two = "i am Two";
return (
hello react.
{isDisplayOne ? one : two} //通过三元表达式代替if-else,如果?号后面的内容过多,建议抽取后通过变量赋值
);
}
```
**Demo3 - JSX中,html标签内部的注释需要用花括号括起来,如:**
```javascript
render() {
return (
hello react.
{/* test annotation */}
);
}
```
**Demo4 - JSX中,使用数组,会将数组中的内容自动按照顺序填充到html标签中,如:**
```javascript
render() {
let arr = [
{/*如果要在jsx中使用内联属性元素,则属性值在赋值的时候需要用双花括号括起来。*/}
1.hello ,
2.world
];
return (
);
}
```
**Demo5 - 在JSX中,html中的一些元素属性:如class,for,需要使用 className 和 htmlFor 来做代替,如:**
```javascript
render() {
return (
{/*以下内容最终生成的html为:hello react. */}
hello react.
);
}
```
**Demo6 - jsx中,属性事件**
```javascript
button
这里在定义点击事件的时候,不再是全小写的“onclick”,而是“onClick”--- C 大写。命名上,类似于camel命名
```
使用:
```javascript
假设在声明了如下方法:
//无参方法
sayHello(){
console.log("say hello");
}
//带参方法
sayHelloTo(name) {
console.log("hello " + name);
}
通过按钮点击事件使用 sayHello方法
< div > button
```
在调用方法的时候,需要注意以下几点:
1. 若调用的方法不带参数,如 sayHello:
- 若调用时方法上带上了圆括号,如 onClick={this.sayHello()},则在页面加载的时候,该方法会自动执行一遍。
- 若调用时没有带圆括号,如 onClick={this.sayHello},则页面加载的时候,该方法不会自动执行,需要点击该按钮后才会被执行。
2. 若调用的方法带参数,如 sayHelloTo:
- 若调用方式为:onClick={this.sayHelloTo('Lucy')},则页面加载的时候,该方法就自动执行,且之后按钮再怎么点击也无效
- 若想让带参方法不自动执行,方法有两种:
- 1.通过箭头函数:onClick={()=>this.sayHelloTo("Lucy")}
- 2.使用bind:onClick={this.sayHelloTo.bind(this,"Lucy")} //第一个参数表示当前指向的对象,这里传的this表示的当前js中定义的class(因为该this是JSX中的this),第二个参数开始就是调用方法的入参
# 5. 组件:Component
一个简单例子:在src目录中创建如下目录和文件

## 5.1 - 创建自定义组件:Student.js
```javascript
Student.js
import React from 'react'
function student(props){
return 大家好,我是学生
}
export default student;
```
## 5.2 - 在App.js中使用Student组件
```javascript
App.js
导入组件:import Student from './Components/Student/Student';
使用组件:
render() {
return (
);
}
```
## 5.3 - 组件中如何传值?
### 5.3.1 - 通过 props
```javascript
Student.js
import React from 'react'
function student(props){
return 大家好,我是学生:{props.name},班级:{props.class}
}
export default student;
```
```javascript
App.js
render() {
return (
);
}
```
### 5.3.2 - 通过 state
- 什么是 state,如何使用?
- state是定义在Component中的一个属性,组件必须是class组件继承自Component
定义 state:
```javascript
App.js
class App extends Component {
{/*定义state*/}
state = {
students:[
{id:1, name:"John", class:"class_A"},
{id:2, name:"Steve", class:"class_C"},
{id:3, name:"Trump", class:"class_A"},
]
}
render() {
return (
);
}
}
```
如何动态修改数据?
- 通过 this.setState()方法
```javascript
changeStudent = () => {
this.setState({
students: [
{ id: 1, name: "John_______", class: "class_A" },
{ id: 2, name: "Steve", class: "class_C" },
{ id: 3, name: "Trump", class: "class_A" },
]
});
}
render() {
return (
修改
);
}
```
Demo1 - 数据的双向绑定:修改年级信息
```javascript
App.js
1. 增加grade信息容器
2. 增加输入行用于更新grade信息
class App extends Component {
state = {
students: [
{ id: 1, name: "John", class: "class_A" },
{ id: 2, name: "Steve", class: "class_C" },
{ id: 3, name: "Trump", class: "class_A" },
],
gradeInfo:"grade one"
}
...
changeGradeInfo = (event)=>{
this.setState({
gradeInfo:event.target.value
})
}
render() {
return (
);
}
}
```
Demo2 - 修改学生姓名
```javascript
App.js
class App extends Component {
...
changeStudentTo = (event,id) => {
let students = this.state.students;
let index = students.findIndex(ent=>ent.id===id);
console.log(index);
let student = students[index];
student.name = event.target.value
students[index] = student;
this.setState({
students: students
});
}
render() {
return (
);
}
}
```
```javascript
Student.js
import React from 'react'
function student(props) {
return (
);
}
export default student;
```
>这里需要注意下,react的event和我们平时认为的JS的event不一样,相关文档见此: https://reactjs.org/docs/events.html
- 什么时候用 state?
- 需要动态改变组建内值的时候
- 需要使用组件的生命周期函数的时候
# 6. React中的样式
## 6.1 - 通过 import 导入样式
在Student.js同级目录创建Student.css
```css
Student.css
div{
color:blue;
}
```
在Student.js中使用该样式
```javascript
import './Student.css'
```
## 6.2 - 直接在组件中定义样式
```javascript
Student.js
import React from 'react'
var myStyle = {
color:"orange",
fontSize:"22px"
}
function student(props) {
return (
);
}
export default student;
```
# 7. 流程控制语句
## 7.1 - 条件判断语句
- 一种是在JSX中使用三元表达式
```html
JSX语法
{this.state.isShowGradeInfo?this.state.gradeInfo:""}
```
- 一种是在JSX语法外,先把需要判断的东西计算出结果后,直接使用结果
```javascript
render() {
let gradeInfo = null;
if(this.state.isShowGradeInfo){
gradeInfo = this.state.gradeInfo;
}
return (
);
}
```
## 7.2 - 循环语句
- 一种是常规的for循环
```javascript
render() {
...
var studentArray = [];
for(let i=0;i )
}
return (
...
{/* {studentArray} */}
{this.state.students.map(student=>{
return
})}
...
);
}
```
- 一种是使用map方法(推荐)
- ```javascript
render() {
...
return (
...
{
this.state.students.map(student=>{
return
});
}
...
);
}
```