1.创建react项目
安装脚手架:create-react-app
npx create-react-app my-app
npm i -g create-react-app
create-react-app my-app
工程目录说明:
-node_modules 依赖包
-public 项目入口
-src 项目资源
index.js 程序入口
App.js 组件
添加、显示与删除功能
2. React类组件实现to do list
App.js
import Combination from './classcom/combination'
function App() {
return (
<Combination />
);
}
export default App;
classcom/combination/index.js
// 类组件
import React, { Component, Fragment } from 'react'
import Input from '../input'
import List from '../list'
// 定义一个类继承React.Component,这样Combination就是一个类组件
class Combination extends Component {
// 初始化响应数据
constructor(props) {
super(props)
this.state = {
msg: '',
list: []
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
// 必须通过setState修改数据才能触发响应式
this.setState({
...this.state,
msg: e.target.value
})
}
addList = () => {
const newList = [...this.state.list]
newList.push(this.state.msg)
this.setState({
...this.state,
list: newList,
msg: ''
})
}
deleteList = (index) => {
const newList = [...this.state.list]
newList.splice(index, 1)
this.setState({
...this.state,
list: newList
})
}
// 必须要定义一个render方法
render() {
const { msg, list } = this.state
return (
<Fragment>
{/*
父组件传递数据到子组件: 通过属性的方式
*/}
<Input msg={msg} handleChange={this.handleChange} addList={this.addList} />
{list.length > 0 ? <ul><List list={list} deleteList={this.deleteList} /></ul> : ''}
</Fragment>
)
}
}
export default Combination
classcom/input/index.js
import React, { Component } from 'react'
class Input extends Component {
render () {
// 接收父组件传递的数据: 通过 this.props
const { msg, handleChange, addList } = this.props
return (
<div>
<input type="text" value={msg} onChange={handleChange} />
<button onClick={addList}>添加</button>
</div>
)
}
}
export default Input
classcom/List/index.js
import React, { Component, Fragment } from 'react'
class List extends Component {
render() {
// 接收父组件传递的数据: 通过 this.props
const { list, deleteList } = this.props
return (
<Fragment>
{
list.map((item, index) => (
<li key={index} onDoubleClick={() => deleteList(index)}>{item}</li>
))
}
</Fragment>
)
}
}
export default List
3.React函数组件实现to do list
App.js
import Combination from './components/combination'
function App() {
return (
<Combination />
);
}
export default App;
components/combination/index.js
import { Fragment, useState } from 'react'
import Input from '../input'
import List from '../list'
/*
1.函数组件: 必须要用return
2.jsx语法:
标签:html和组件标签,组件标签首字母必须大写
class样式必须使用className代替
3.只能有一个根节点,不能使用template,使用react里面的Fragment组件
4.使用变量:
<h1 className={a}>{msg}</h1> 属性不能使用引号包裹
*/
function Combination() {
// 函数组件中的变量不会在模板中相应变化
// 在16.8+可以使用react.useState函数实现响应式变化
// useState()返回一个数组
// 包含2个元素,第一个元素是变量,第二个元素是改变变量的方法
// 参数是变量的默认值
let [msg, setMsg] = useState('')
let [list, setList] = useState([])
let handleChange = (event) => {
setMsg(event.target.value)
}
let addToList = () => {
const newList = [...list, msg] // 生成一个新的列表数据才能触发响应
setList(newList)
// 清空表单
setMsg('')
}
let deleteList = (index) => {
list.splice(index, 1)
const newList = [...list]
// 删除双击的选项
setList(newList)
}
return (
<Fragment>
{/*
组件通信:
父 ——> 子: 通过属性的方式
*/}
<Input text = {msg} handleChange = {handleChange} addToList = {addToList}/>
<List list = {list} deleteList = {deleteList} />
</Fragment>
)
}
export default Combination
components/input/index.js
function Input(props) {
// 接收父组件传递过来的数据,通过参数的形式
// 子组件改变父组件的数据,通过调用父组件的方法实现
const { text, handleChange, addToList} = props
return (
<div>
<input type="text" value={text} onChange={handleChange} /> <button onClick={addToList}>添加</button>
</div>
)
}
export default Input;
components/list/index.js
function List(props) {
const { list, deleteList } = props
return (
<ul>
{
list.map((item, index) => (
<li key={index}
onDoubleClick={() => deleteList(index)}>{item}</li>
))
}
</ul>
)
}
export default List