React特点
用于构建用户界面的 js库、框架
声明式:数据改变时,能够有效地更新并正确地渲染组件;以声明方式编写UI,使得代码更可靠,利于调试
准备工作
-
安装:局部安装
npx create-react-app todo-list
npx–>npm 5.2+附带的package运行工具
-
运行:
npm start
默认在3000端口下运行 -
删除src文件夹内容,更改为如图下所示

)
./App.js
→ 存放最外层组件,即父组件
引入子组件后,要在render方法中return组件,首字母大写
可以使用 或两种方式渲染组件
必须使用闭合标签<></> 、
…包裹传值,父组件-→后代组件的数据传递,通过属性传递使用特定属性值
import React, { Component } from 'react'
//没有./components/index.js文件时,引入子组件的方法
// import TodoHeader from './components/TodoHeader'
// import TodoInput from './components/TodoInput'
// import TodoList from './components/TodoList'
////有./components/index.js文件时,引入子组件的方法
import {
TodoHeader,
TodoInput,
TodoList
} from './components'
export default class App extends Component {
constructor() {
super()
this.state = {
title: '待办事项列表',
subtitle: '今日事,今日毕',
index: 3,
todos: [
{
id: 1,
title: '吃饭',
isCompleted: false
},
{
id: 2,
title: '睡觉',
isCompleted: true
}
]
}
}
// 修改完成状态的方法
completedChange = (id) => {
console.log(this.state.index)
// 修改状态数据,需要显式调用 setState() 方法来修改
// setState() 是异步更新状态
this.setState({
todos: this.state.todos.map(todo => {
if (todo.id === id) {
todo.isCompleted = !todo.isCompleted
}
return todo
}),
// index: this.state.index + 5
}, () => {
console.log('回调:', this.state.index)
})
console.log(this.state.index)
}
deleteTodoItem = (id) => {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id)
})
}
addTodoItem = (title) => {
this.setState({
todos: [
...this.state.todos,
{
id: this.state.index,
title,
isCompleted: false
}
],
index: this.state.index + 1
})
}
render() {
return (
<>
{/* 注释: */}
<TodoHeader title={this.state.title} subtitle={this.state.subtitle}>
<h1>asdflkjlasfd</h1>
<h3>sadflk</h3>
</TodoHeader>
<TodoInput
addTodoItem={this.addTodoItem}
/>
<TodoList
todos={this.state.todos}
completedChange={this.completedChange}
deleteTodoItem={this.deleteTodoItem}
/>
</>
)
}
}
./components/文件夹/XX.js
→ 存放后代组件
分别创建文件夹,每个文件夹中,设置不同的js文件,用来存放后代组件;
js文件最好命名为index.js,便于引入
传值,子组件-→父组件的数据传递,通过props.属性名或者props.children获取数据
两种写法
//ES6写法
state = {
inputValue: 'abc'
}
//普通写法
constructor () {
this.state = {
inputValue: ''
}
}
./components/index.js
方法一:
import TodoHeader from './TodoHeader'
import TodoInput from './TodoInput'
import TodoList from './TodoList'
export {
TodoHeader,
TodoInput,
TodoList
}
方法二:
as →重命名
export { default as TodoHeader } from './TodoHeader'
export { default as TodoInput } from './TodoInput'
export { default as TodoList } from './TodoList'
NOTE:
-
修改状态===更新数据
-
使用结构赋值方式引入的优点
import ReactDom from 'react-dom' ReactDom.render() //结构赋值方式 import { render } from 'react-dom' render()
-
JSX在react包中
-
用数据驱动渲染,减少DOM操作。
-
组件间的数据传输
子组件-→父组件的数据传递 通过props.属性名或者props.children获取数据
父组件通过属性将子组件要用的方法传递下来,在子组件中调用对应的方法,传递参数,将数据传递出去
父组件-→后代组件的数据传递 通过属性传递使用特定属性值,状态提升到共同会用到的父组件中
-
在 React 中,构造函数仅用于以下两种情况:
1 通过给 this.state 赋值对象来初始化内部 state。
2 为事件处理函数绑定实例 -
lodash
_.cloneDeep(value) 这个方法类似 _.clone,但它会递归拷贝 value。(也叫深拷贝)。
-
VScode中可以安装ES7插件,这样在js文件中
输入ref+回车→引入函数式组件,有state,属于无状态组件,用Hook添加
import React from 'react' export default function App() { return ( <div> </div> ) }
输入rcc+回车→引入类组件,无state,属于有状态组件
import React, { Component } from 'react' export default class App extends Component { render() { return ( <div> </div> ) } }