React实现一个简单的TodoList

作为React入门教程,todoList经常被哪来做入门教程,今天我们也来手把手搭建个todolist,简单粗暴,方便学习

1:脚手架搭建一个项目react-study

create-react-app  react-study 

2:进入目录,启动项目

cd  react-study
npm  start

3:新建一个TodoList.js

import React,{Component,Fragment} from 'react';
import './App.css';
import TodoItem from './TodoItem'

class TodoList extends Component{
	constructor(props) {
	    super(props);
		this.state={
			value:'',
			list:[]
		}
	}
	render(){
		return(
			<Fragment>
				<label htmlFor="username">用户名:</label>
				<input type='text'  id="username" className='input' value={this.state.value}
				onChange={this.changeValue}
				 /><button onClick={this.submitHandle}>提交</button>
				<ul>
				{
					this.state.list.map((item,index)=>{
						return (
							<div key={index}>
								<TodoItem content={item} index={index}
								 deleteOne={this.deleteOne}
								 />
								{/* 注意这里有个坑,子组件TodoItem明明加了key一直报错,是因为要加到父级div上面才可以
								<li  onClick={this.remove}
								>
								{this.props.content}
								</li>	
								*/}
							</div> 
							)
					})
				}	
				</ul>	
			</Fragment>
		)
	}
	//input 改变
	changeValue=(e)=>{
		let  v =e.target.value;
		this.setState({
			value:v
		})
	}
	//新增
	submitHandle=(e)=>{
		let  newlist =this.state.list;
		let  value = this.state.value;
		//旧方法  数组添加 
		//newlist.concat().push(this.state.value);
		this.setState({
			list:[value,...newlist]   //es6 数据合并 
		})
		this.state.value='';
	}
	deleteOne=(key)=>{
		//官方所 state不要直接修改  不允许我们直接改变 性能不好
		//注意这里一定要复制一份再操作
		var list =[...this.state.list];
		//操作复制的这一份 坑
		list.splice(key,1);
		//重新设置
		this.setState({
			list
		})
	}
	
	
}

export default TodoList;

注意这里我们单独把列表抽离为一个子组件
TodoItem .js

import React,{Component} from 'react';

class TodoItem extends Component{
	constructor(props) {
	    super(props);
	}
	render(){
		return(
			<li  onClick={this.remove}>
			{this.props.content}
			</li>
		)
	}
	//注意this的指向
	remove=()=>{
		//es6 数据结构 ,获取父组件的方法
		const {deleteOne,keys}=this.props;
		//执行父组件的deleteOne方法,并且把索引传递回去
		deleteOne(keys)
	}
	
	
}

export default TodoItem;

ps:抽离后一定要注意this的指向。。。。
image.png

大功告成,如果想更加完美,就优化代码,更加符合react规范 。。。

import React,{Component,Fragment} from 'react';
import './App.css';
import TodoItem from './TodoItem'

class TodoList extends Component{
	constructor(props) {
	    super(props);
		this.state={
			value:'',
			list:[]
		}
	}
	render(){
		return(
			<Fragment>
				<label htmlFor="username">用户名:</label>
				<input type='text'  id="username" className='input' value={this.state.value}
				onChange={this.changeValue}
				 /><button onClick={this.submitHandle}>提交</button>
				<ul>
				{
					this.getTodo()
				}	
				</ul>	
			</Fragment>
		)
	}
	getTodo(){
		return this.state.list.map((item,index)=>{
			return (
				<div key={index}>
					<TodoItem content={item} index={index}
					 deleteOne={this.deleteOne}
					 />
					{/* 注意这里有个坑,子组件TodoItem明明加了key一直报错,是因为要加到父级div上面才可以
					<li  onClick={this.remove}
					>
					{this.props.content}
					</li>	
					*/}
				</div> 
				)
		})
		
	}
	//input 改变
	changeValue=(e)=>{
		let  v =e.target.value;
		// this.setState({
		// 	value::v
		// })
		//使用最新版的setState  注意返回的是() 坑哦 
		//异步哦  v的值要提前存储起来使用哦
		this.setState(()=>({
			value:v
		}))
	}
	//新增
	submitHandle=(e)=>{
		let  newlist =this.state.list;
		let  value = this.state.value;
		//newlist.push(this.state.value);
		// this.setState({
		// 	list:[value,...newlist]   //es6 数据合并 
		// })
		//this.state.value='';
		//es6 返回的新函数 对象  注意prevState 保存的是之前的state
		//prevState   ==  this.state
		this.setState((prevState)=>({
			list:[prevState.value,...prevState.list],
			value:''
		}))
		
	}
	deleteOne=(key)=>{
		/*
		//官方所 state不要直接修改  不允许我们直接改变 性能不好
		//注意这里一定要复制一份再操作
		
		//重新设置
		this.setState({
			list
		})
		*/
		//es6  最新写法
		this.setState((prevState)=>{
			var list =[...prevState.list];
			//操作复制的这一份 坑
			list.splice(key,1);
			return {
				list
			}
			}
			
		)
		
	}
	
	
}

export default TodoList;

优化方案如下:
1:使用了箭头函数改变this指向,当然也可以再constructor里面bind(this)
2:使用了抽离函数ui,在ui中把渲染抽离getTodo方法,方便维护
3:使用了最新的setState,可以返回一个对象函数,注意返回对象一定要加(),否则报错哦
4:使用了ES6的props结构,简化代码
5:使用了最新setState中的prevState,可以直接获取state状态啦,注意看代码写法
@最后再说一句,父组件可以给子组件传递值,但是子组件千万不能修改这个传递的值,这个值是只读属性,修改会报错,就比如这里的list如果传递过来,千万不能修改,修改报错!!

image.png

OK,大功告成,每天学习一点点,加油~~~~~~~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值