demo 介绍
该demo 就是帮你快速复习 react 的 事件传值,子组件传值,父传子,事件绑定,交互逻辑,react 语法,该demo有,显示隐藏列表,增加内容,删除todo,双击内容编辑是input 框的内容回填,拉代码的时候注意组件的路径不然会报错的哦。 最下面有记的笔记。
列表(子组件)
import React from 'react';
import PropTypes from 'prop-types';
import './hello.css'
export default class List3 extends React.Component {
constructor(props) {
super(props)
this.state = {
showElem: -1,
editValue:''
}
}
// 父组件向子组件传递数据
static propTypes = {
hideConponent: PropTypes.func.isRequired,
remove:PropTypes.func.isRequired
}
// 子级的删除事件
delete = (val) => {
console.log(val);
let { remove } = this.props
remove(val)
}
// 编辑复选框的状态
editChecked = (val) => {
let {editChecked} = this.props
console.log(val)
editChecked(val)
}
trueNum = () => {
return this.props.list.reduce((num,item) => num += item.checked,0)
}
// false
falseNum = () => {
return this.props.list.reduce((num,item) => num += !item.checked,0)
}
// 是否显示编辑数据
editTextFlag = (e) => {
console.log(e);
this.state.showElem = e.index
this.setState({
state: this.state.showElem,
editValue:e.item.name
})
console.log(e);
console.log(this.state.editValue);
}
// 失去焦点进行关闭 input 输入框
editTextFlag2 = (e) => {
let {editTextFlag} = this.props
this.state.showElem = e.index
this.setState({
state: this.state.showElem,
})
console.log(e);
console.log(this.state.editValue);
// 拿到当前的 id 和 修改后的值
editTextFlag({id:e.item.id,name:this.state.editValue})
}
// 拿到修改后的值
onInputValue = (e) => {
this.setState({
editValue: e.target.value,
})
}
// 渲染一个组件 吧 html 渲染
render() {
return (
<>
<h2 className='tit'>未完成的任务{
this.falseNum()
}</h2>
{
this.props.list.map((item, index) => {
if (!item.checked) {
return <div key={index} className='list'>
<input onChange={this.editChecked.bind(this,item.id)} defaultChecked={item.checked} className='checked' type="checkbox" name="" id="" />
{
this.state.showElem == index ? <input onInput={this.onInputValue} defaultValue={this.state.editValue} onBlur={this.editTextFlag2.bind(this, {item:item,index:-1})} type="text" /> :
<div className='content' style={{ display: this.state.showElem }} onDoubleClick={this.editTextFlag.bind(this, {item:item,index:index})}> {item.name}</div>
}
<div><button className='removeBtn' onClick={this.delete.bind(this, index)}>删除</button></div>
</div>
}
})
}
<h2 className='tit'>已完成的任务{ this.trueNum()}</h2>
{
this.props.list.map((item, index) => {
if (item.checked) {
return <div key={index} className='list'>
<input onChange={this.editChecked.bind(this,item.id)} defaultChecked={item.checked} className='checked' type="checkbox" name="" id="" />
<div>{item.name}</div>
<div><button className='removeBtn' onClick={this.delete.bind(this,index)}>删除</button></div>
</div>
}
})
}
<button className='hidBtn' onClick={this.props.hideConponent}>隐藏List3组件</button>
</>
);
}
}
input (子组件)
import React from "react"
export default class StyleModel extends React.Component {
// 子向父级传递数据
oninputh = (e) => {
let { oninputs } = this.props;
oninputs(e.target.value)
}
// 鼠标按下
onKeyDown = (e) => {
let { add } = this.props;
if(e.keyCode === 13) {
add()
}
}
render() {
return (<div>
请输入内容:<input onKeyDown={this.onKeyDown} onInput={this.oninputh} type="text" />
</div>)
}
}
主组件
import React, { Component } from 'react';
import List3 from './components/List3.jsx';
import Myinput from './components/myinput.jsx'
export default class App extends Component {
constructor(...args) {
super(...args);
this.state = {
isShowList3: false,
list: [
{
name: '孙志阿红',
id: 24123,
checked: false,
isInput:true
},
{
name: '孙志豪',
id: 545,
checked: true,
isInput:true
},
],
inputValue:''
};
}
// 用来显示列表
showConponent = () => {
this.setState({
isShowList3: true,
});
}
// 用来关闭列表
hideConponent = () => {
this.setState({
isShowList3: false,
});
}
// 增加数据
add = () => {
if(this.state.inputValue.trim() == '') return alert('输入内容为空')
let obj = { isInput:true,checked:false, name:this.state.inputValue,id:new Date().getTime(),time:new Date().toLocaleString() }
this.state.list.unshift(obj)
this.setState({
list: this.state.list,
})
}
// 删除每行的数据
remove = (index) => {
this.state.list.splice(index, 1)
this.setState({
list:this.state.list
})
}
// 子组件传过来的值
oninputs = (val) => {
this.setState({
inputValue:val
})
console.log(this.state.inputValue)
}
// 编辑复选框的状态
editChecked = (val) => {
this.state.list.forEach(item => {
if (item.id == val) {
console.log(item.checked)
item.checked = !item.checked
}
})
this.setState({
list:this.state.list
})
console.log(this.state.list)
}
// 编辑 input 的输入框
editTextFlag = (obj) => {
this.state.list.forEach((item) => {
if (obj.id == item.id) {
item.name = obj.name
}
})
this.setState({
list:this.state.list
})
}
render() {
return (
<div className='warpBox'>
<h2 className='title'>ToDoList ReactNb 版权:孙志豪</h2>
{/* 封装的input的事件 */}
<div className='header-input'>
<Myinput add={this.add} oninputs={this.oninputs} /><button onClick={this.add}>添加</button>
</div>
<button onClick={this.showConponent}>显示Lists组件</button>
{
this.state.isShowList3 ?
<List3 editTextFlag={this.editTextFlag} editChecked={this.editChecked} remove={this.remove} list={this.state.list} hideConponent={this.hideConponent} />
:
null
}
</div>
);
}
}
react笔记
文件的介绍
README.md 这个文件主要作用就是对项目的说明 编写这个文件可以使用Markdown的语法来编写。
package.json 这个文件是webpack配置和项目包管理文件,项目中依赖的第三方包(包的版本)和一些常用
命令配置都在这个里边进行配置,
package.lock.json 就是锁定安装时的版本号,并且需要上传到git,以保证其他人再npm install 时大
家的依赖能保证一致。
gitignore 这个是git的选择性上传的配置文件 比如说是 node_modules 不用上传就可以在 gitignore 里面配置
node_modules 这个文件夹就是我们项目的依赖包,脚手架已经都给我们下载好了
public 公共文件,里边有公用模板和图标等一些东西。
- favicon.ico: 这个是网站或者说项目的图标
- index.html: 首页的模板文件
- mainifest.json:移动端配置文件
- index.js: 这个就是项目的入口文件
- index.css:这个是index.js里的CSS文件
- app.js: 这个文件相当于一个方法模块,也是一个简单的模块化编程。
- serviceWorker.js:这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。
src 主要代码编写文件,这个文件夹里的文件对我们来说最重要,都需要我们掌握。
react 创建子组件
- 在src下面创建一个 component 文件夹 新建一个组件后缀要以 jsx 为结尾 在 父组件引入使用即可
import React from "react"
export default class StyleModel extends React.Component {
// 这个是 render 函数创建dom 最后在返回 dom
render() {
return (<div>
我是子组件
</div>)
}
}
react 的跟标签
- <React.Fragment></React.Fragment> 的根标签 空标签
- <></> 作为跟标签 可以不用解析为 dom 元素,不会出现到页面。
数据的更改
- 需要使用 this.setState 来进行修改
// 编辑 input 的输入框
editTextFlag = (obj) => {
this.state.list.forEach((item) => {
if (obj.id == item.id) {
item.name = obj.name
}
})
this.setState({
list:this.state.list
})
}
列表的渲染
- 最后记得要有返回值哦
<div>
{
this.props.list.map((item, index) => {
return <div> {index}</div>
})
}
</div>
react 的样式绑定
- 设置类名 className 相当于 css 的 class
- react 绑定样式需要 动态绑定样式
// style 绑定样式
style={{dispaly:"none",transform:"rotate(2deg)"}}
// 控制元素的显示和隐藏
true ? div : ul
react 的绑定事件
// 单击事件
onClick={this.delete.bind(this, index)
// 回车事件
onKeyDown={this.onKeyDown}
onKeyDown = (e) => {
if(e.keyCode === 13) {
}
}
// 双击事件
onDoubleClick={this.fn}
react 父传子
- 父组件的值传给子组件
// 父组件
constructor(...args) {
super(...args);
this.state = {
isShowList3: false,
};
}
// 标签
<List3 isShowList3={this.state.isShowList3} />
// 子组件
//子组件接收的第一种方式
constructor(props) {
super(props)
}
// 子组件接收的第二种方式
let {editChecked} = this.props
react 子传父
- 子组件通过事件传给父组件
// 父组件的事件
onInputValue = (e) => {
console.log(e)
}
// 子组件绑定自定义事件
<List3 onInputValue={this.onInputValue} />
// 子组件的标签绑定事件 这个需要 bind(this,item.id) 来改变this指向 通过item.id 传过去
<input onInput={this.onInputValue.bind(this,item.id)} type="text" />
// 在子组件通过 props 结构父组件传过来的事件
onInputValue = (e) => {
let { onInputValue } = this.props;
onInputValue(e.target.value)
}