首页 > 代码库 > 初学react---todolist实例
初学react---todolist实例
最近刚学习了阮一峰老师的react入门教学-----React 入门实例教程
然后大概理解了React的用法,然后比较迷茫不知道react可以干啥,看评论说先做个todolist,然后我就看着一些教程试着做了个。
todolist主要是实现一个增查改删的功能,结构大概长这样。
长得虽然很丑(还没写样式),但他的结构还是挺清晰的,由一个总的父组件和两个子组件组成。然后我们就可以这样写:
//总组件 var TodoList = React.createClass({ render:function(){ return( //添加子组件 <div> <TypeNew /> <ListTodo /> </div> ); } }); //输入框组件用于新增数据 var TypeNew = React.createClass({ render:function(){ return( <form> <input type="text" ref="inputnew" placeholder="typing a newthing todo" autoComplete="off" /> <input type="button" value="http://www.mamicode.com/提交" /> </form> ); } }); //用于展示数据、删除、修改数据 var ListTodo = React.createClass({ render:function(){ return( <ul id="todolist"> {} </ul> ); } });
React.render(<TodoList />,document.body);
查看数据:
展示、查看数据主要是考虑一个将数据存在哪的,而react的思想是建议将数据存储在父组件的state中,通过props传给子组件。
//总组件 var TodoList = React.createClass({ //父组件statec存储数据 getInitialState:function(){ return{ todolist:[] }; }, render:function(){ return( //添加子组件 <div> <TypeNew todo={this.state.todolist} /> <ListTodo todo={this.state.todolist} /> </div> ); } }); //输入框组件用于新增数据 var TypeNew = React.createClass({ render:function(){ return( <form> <input type="text" ref="inputnew" placeholder="typing a newthing todo" autoComplete="off" /> <input type="button" value="http://www.mamicode.com/提交" /> </form> ); } }); //用于展示数据、删除、修改数据 var ListTodo = React.createClass({ render:function(){ return( <ul id="todolist"> { //遍历数据 this.props.todo.map(function(item,i){ return( <li> <span>{item}</span> <button>删除</button> <button >修改</button> </li> ) } } </ul> ); } }); React.render(<TodoList />,document.body);
此时只要在父组件的state中添加数据就可以在子组件中展示数据了。
增加数据:
在react中只要state发生改变,组件就会重新渲染一遍,所以数据的增加就是通过改变state来增加的。如何改变state呢,就是通过输入框组件的事件来改变数值然后再通过回调来改变state。
var TodoList = React.createClass({ getInitialState:function(){ return{ //state用来控制todolist todolist:[] }; }, handleChange:function(rows){ //当发生增删改查时改变state重新渲染 this.setState({ todolist:rows }); }, render:function(){ return( //添加子组件 <div> <TypeNew todo={this.state.todolist} add={this.handleChange}/> <ListTodo todo={this.state.todolist} /> </div> ); } }); //输入框组件 var TypeNew = React.createClass({ handleAdd:function(){ //获取真实DOM 虚拟DOM无法获取表单元素的数据 var inputDom = this.refs.inputnew.getDOMNode(); //获取数据 var newthing = inputDom.value.trim(); var rows = this.props.todo; //如果输入的数据为空值则返回提示无法添加 if(newthing == ""){ alert("数据不能为空"); return; } //在数组内添加新数据 rows.push(newthing); //回调改变state this.props.add(rows); //清空输入框 inputDom.valuehttp://www.mamicode.com/= ""; }, render:function(){ return( <form> <input type="text" ref="inputnew" placeholder="typing a newthing todo" autoComplete="off" />
{//添加点击事件} <input type="button" value="http://www.mamicode.com/提交" onClick={this.handleAdd}/> </form> ); } });
删除数据:
删除数据与增加数据同理,通过props传递数据然后通过点击事件回调给父组件改变state。
//总组件 var TodoList = React.createClass({ getInitialState:function(){ return{ //state用来控制todolist todolist:[] }; }, handleChange:function(rows){ //当发生增删改查时改变state重新渲染 this.setState({ todolist:rows }); }, render:function(){ return( //添加子组件 <div> <TypeNew todo={this.state.todolist} add={this.handleChange}/> <ListTodo todo={this.state.todolist} change={this.handleChange}/> </div> ); } }); //ListTodo 用于展示、修改、删除数据 var ListTodo = React.createClass({ //删除数据 handleDel:function(e){ var rows = this.props.todo; //获取index var index = e.target.getAttribute("data-index"); //根据index删除数据 rows.splice(index,1); //回调给父组件改变state this.props.change(rows); }, render:function(){ return( <ul id="todolist"> { this.props.todo.map(function(item,i){ return( <li> <span>{item}</span> <button onClick={this.handleDel} data-index={i} >删除</button> <button >修改</button> </li> ); }.bind(this)) } </ul> ); } });
修改数据:
我的实现思路是,在<ListTodo />子组件中设置state用于记录是否按了修改按钮,如果按了修改按钮就将该处的list变成type框重新渲染,在type框进行修改后,点击确认按钮则发生事件然后回调给父组件更新事件。
var TodoList = React.createClass({ getInitialState:function(){ return{ //state用来控制todolist todolist:[] }; }, handleChange:function(rows){ //当发生增删改查时改变state重新渲染 this.setState({ todolist:rows }); }, render:function(){ return( //添加子组件 <div> <TypeNew todo={this.state.todolist} add={this.handleChange}/> <ListTodo todo={this.state.todolist} change={this.handleChange}/> </div> ); } }); //输入框组件 var TypeNew = React.createClass({ handleAdd:function(){ //获取真实DOM 虚拟DOM无法获取表单元素的数据 var inputDom = this.refs.inputnew.getDOMNode(); //获取数据 var newthing = inputDom.value.trim(); var rows = this.props.todo; //如果输入的数据为空值则返回提示无法添加 if(newthing == ""){ alert("数据不能为空"); return; } //在数组内添加新数据 rows.push(newthing); //回调改变state this.props.add(rows); //清空输入框 inputDom.valuehttp://www.mamicode.com/= ""; }, render:function(){ return( <form> <input type="text" ref="inputnew" placeholder="typing a newthing todo" autoComplete="off" /> <input type="button" value="http://www.mamicode.com/提交" onClick={this.handleAdd}/> </form> ); } }); //ListTodo 用于展示、修改、删除数据 var ListTodo = React.createClass({ //子组件state用于记录修改状态 getInitialState:function(){ return{ //changenum记录是哪一个list要修改,changevalue记录要修改的list的值 changenum:-1, changevalue:"" } }, //删除数据 handleDel:function(e){ var rows = this.props.todo; var index = e.target.getAttribute("data-index"); rows.splice(index,1); this.props.change(rows); //防止修改后按删除按钮产生bug this.setState({ changenum:-1 }); }, //点击修改按钮后改变state handleChange:function(e){ var index=e.target.getAttribute("data-index"); var msg =this.props.todo[index]; this.setState({ changenum:index, changevalue:msg }); }, //react中设置了value后无法进行输入,根据API 此办法解决 handleText:function(e){ this.setState({ changevalue:e.target.value }) }, //保存事件 获取修改后的数据 与增加数据同理 handleSave:function(){ var inputDom = this.refs.inputnew.getDOMNode(); var newthing = inputDom.value.trim(); var rows = this.props.todo; if(newthing == ""){ alert("数据不能为空"); return; } var index = this.state.changenum; //rows[index]改变为新的数据 rows[index] = newthing; //回调 this.props.change(rows); //改变当前state回到展示状态 this.setState({ changenum:-1 }); }, render:function(){ return( <ul id="todolist"> { this.props.todo.map(function(item,i){ //如果有点击修改则将此处渲染成type框 if(this.state.changenum == i) { return( <li> <input type="text" ref="inputnew" value=http://www.mamicode.com/{this.state.changevalue} onChange={this.handleText} /> <button onClick={this.handleSave} >确定</button> </li> ) } else{ return( <li> <span>{item}</span> <button onClick={this.handleDel} data-index={i} >删除</button> <button onClick={this.handleChange} data-index={i} >修改</button> </li> ); } }.bind(this)) } </ul> ); } }); React.render(<TodoList />, document.body );
总结:
感觉React的框架确实挺好用!这种模块化的思想太棒了,以前写东西都是一个功能一个功能的写,改起来好麻烦= =,react感觉就不同,感觉模块化的构造能让整个代码结构更清晰,希望之后能学习更多react知识啊。
初学react---todolist实例