本案例在上一篇的案例(React组件之间通过Props传值的技巧(小案例,帮助体会理解props、state、受控组件和非受控组件等))的基础上加强功能和用户体验,但是当然还有很多需要改进的地方,后期一步步慢慢增强:

import React,{Component} from 'react';
import {render} from 'react-dom';
import './index.css'; class CommentInput extends Component{
constructor(){
super();
this.state={
username:'',
content:''
}
} handleUsernameChange=(event)=>{
this.setState({
username:event.target.value
})
}; handleContentChange=(event)=>{
this.setState({
content:event.target.value
})
}; handleSubmit=()=>{
if(this.props.submit){
this.props.submit({
username:this.state.username,
content:this.state.content,
createTime:+new Date()
})
}
this.setState({
content:''
})
}; handleUsernameHold=(event)=>{
localStorage.setItem('username',event.target.value)
}; componentWillMount(){
const username=localStorage.getItem('username');
if(username){
this.setState({username})
}
} componentDidMount(){
this.input.focus();
}; render(){
return(
<div className='comment-input'>
<div className='comment-field'>
<span className='comment-field-name'>用户名:</span>
<div className='comment-field-input'>
<input
ref={(input)=>this.input=input}
value={this.state.username}
onBlur={this.handleUsernameHold}
onChange={this.handleUsernameChange}
/>
</div>
</div>
<div className='comment-field'>
<span className='comment-field-name'>评论内容:</span>
<div className='comment-field-input'>
<textarea
value={this.state.content}
onChange={this.handleContentChange}
/>
</div>
</div>
<div className='comment-field-button'>
<button onClick={this.handleSubmit}>
发布
</button>
</div>
</div>
)
}
} class CommentList extends Component{ constructor(){
super();
this.state={
items:[]
}
} render(){
return(
<div>
{this.props.items.map((item,index)=><Comment deleteItem={this.props.deleteItem} item={item} index={index} key={index}/>)}
</div>
)
}
} class Comment extends Component{
constructor(){
super();
this.state={
timeString:''
}
} handleTimeString=()=>{
const item=this.props.item;
const duration=(+Date.now()-item.createTime)/1000;
return duration>60?`${Math.round(duration/60)}分钟前`:`${Math.round(Math.max(duration,1))}秒前`;
}; handleDelete=()=>{
if(this.props.deleteItem){
this.props.deleteItem(this.props.index)
}
}; render(){
return(
<div className='comment'>
<div className='comment-user'>
<span className='comment-username'>{this.props.item.username} </span>:
</div>
<p>{this.props.item.content}</p>
<span className="comment-delete" onClick={this.handleDelete}>删除</span>
<span className="comment-createdtime">
{this.handleTimeString()}
</span>
</div>
)
}
} class CommentApp extends Component{
constructor(){
super();
this.state={
items:[]
}
} handleSubmit=(item)=>{
this.state.items.push(item);
this.setState({
items:this.state.items
});
localStorage.setItem('items',JSON.stringify(this.state.items))
}; handleDelete=(index)=>{
console.log(index);
this.state.items.splice(index,1);
this.setState({
items:this.state.items
});
localStorage.setItem('items',JSON.stringify(this.state.items))
}; componentWillMount(){
let items=localStorage.getItem('items');
if(items){
items=JSON.parse(items);
this.setState({items})
}
}; render(){
return(
<div className="wrapper">
<CommentInput submit={this.handleSubmit} />
<CommentList deleteItem={this.handleDelete} items={this.state.items}/>
</div>
)
}
} class Index extends Component{
render(){
return(
<div>
<CommentApp/>
</div>
)
}
} render(<Index/>,document.getElementById('root'));
body {
margin:;
padding:;
font-family: sans-serif;
background-color: #fbfbfb;
} .wrapper {
width: 500px;
margin: 10px auto;
font-size: 14px;
background-color: #fff;
border: 1px solid #f1f1f1;
padding: 20px;
} /* 评论框样式 */
.comment-input {
background-color: #fff;
border: 1px solid #f1f1f1;
padding: 20px;
margin-bottom: 10px;
} .comment-field {
margin-bottom: 15px;
display: flex;
} .comment-field .comment-field-name {
display: flex;
flex-basis: 100px;
font-size: 14px;
} .comment-field .comment-field-input {
display: flex;
flex:;
} .comment-field-input input,
.comment-field-input textarea {
border: 1px solid #e6e6e6;
border-radius: 3px;
padding: 5px;
outline: none;
font-size: 14px;
resize: none;
flex:;
} .comment-field-input textarea {
height: 100px;
} .comment-field-button {
display: flex;
justify-content: flex-end;
} .comment-field-button button {
padding: 5px 10px;
width: 80px;
border: none;
border-radius: 3px;
background-color: #00a3cf;
color: #fff;
outline: none;
cursor: pointer;
} .comment-field-button button:active {
background: #13c1f1;
} /* 评论列表样式 */
.comment-list {
background-color: #fff;
border: 1px solid #f1f1f1;
padding: 20px;
} /* 评论组件样式 */
.comment {
position: relative;
display: flex;
border-bottom: 1px solid #f1f1f1;
margin-bottom: 10px;
padding-bottom: 10px;
min-height: 50px;
} .comment .comment-user {
flex-shrink:;
} .comment-username {
color: #00a3cf;
font-style: italic;
} .comment-createdtime {
padding-right: 5px;
position: absolute;
bottom:;
right:;
padding: 5px;
font-size: 12px;
} .comment:hover .comment-delete {
color: #00a3cf;
} .comment-delete {
position: absolute;
right:;
top:;
color: transparent;
font-size: 12px;
cursor: pointer;
} .comment p {
margin:;
/*text-indent: 2em;*/
} code {
border: 1px solid #ccc;
background: #f9f9f9;
padding: 0px 2px;
}

React评论展示案例(包含知识点:state、props、ref、React声明周期、localStorage本地存储等)的更多相关文章

  1. React基础篇(2) -- state&props&refs

    内容简介 state props refs 行内样式及动态类名 state 基本介绍 React 把组件看成是一个状态机(State Machines).通过与用户的交互,实现不同状态,然后渲染 UI ...

  2. (尚030)Vue_案例_存储数据(localStorage本地存储技术)

    当刷新页面时,会变为原来的状态 1.问题:当我刷新是不希望改变原来状态 需要缓存我当前的数据 2.究竟是缓存在内存里还是在文件里??? 缓存在文件里,因为浏览器关闭了,内存就没了;而我们需要重新打开浏 ...

  3. 从 0 到 1 实现 React 系列 —— 2.组件和 state|props

    看源码一个痛处是会陷进理不顺主干的困局中,本系列文章在实现一个 (x)react 的同时理顺 React 框架的主干内容(JSX/虚拟DOM/组件/生命周期/diff算法/setState/ref/. ...

  4. react基础语法(五) state和props区别和使用

    props的验证: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  5. React 三大属性state,props,refs以及组件嵌套的应用

    React 三大属性state,props,refs以及组件嵌套的应用 该项目实现了一个简单的表单输入添加列表的内容 代码如下 <!DOCTYPE html> <html> & ...

  6. react 也就这么回事 05 —— 组件 & Props

    什么是组件:用来实现局部功能的可复用代码片段 比如很多界面会用到"分页"功能,因此可以将它封装成独立的组件 这样用到分页的界面只需引入该组件而不必重新写代码 1 定义组件 在 Re ...

  7. react 入坑笔记(三) - Props

    React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...

  8. React文档(六)state和生命周期

    想一下之前的章节时钟的例子. 目前为止我们只学习了一直方式去更新UI. 我们调用ReactDOM.render()方法去改变渲染的输出: function tick() { const element ...

  9. 前端笔记之React(二)组件内部State&React实战&表单元素的受控

    一.组件内部的State 1.1 state state叫状态,是每一个类式组件都有的属性,但函数式组件,没有state. state是一个对象,什么值都可以定义. 在任何类式组件的构造函数中,可以用 ...

随机推荐

  1. jquery计算两个日期的相差天数

    var days = daysBetween('2016-11-01','2016-11-02'); /** * 根据两个日期,判断相差天数 * @param sDate1 开始日期 如:2016-1 ...

  2. 实现IE下兼容CSS3的圆角效果

    有些CSS3的牛逼的效果在IE下展示不出来是最烦人的啦,在项目中做的圆角效果到了IE下一堆方块....忒尴尬了...,找了个替代解决方案 1.首先下载一个js插件PIE.js百度一搜都是的,我也就不写 ...

  3. 【C/C++】链表的理解与使用

    转载自:http://blog.csdn.NET/xubin341719/article/details/7091583/ 最近不是太忙,整理些东西,工作也许用得到. 1,为什么要用到链表 数组作为存 ...

  4. Linux下使用fstatfs/statfs查询系统相关信息

    Linux下使用fstatfs/statfs查询系统相关信息 1.   功能 #include < sys/statfs.h > int statfs(const char *path, ...

  5. spark资料下载

    很全的spark资料下载,包含pdf书籍和培训学校视频教程, 1.spark多语言编程:spark多语言开发 2.tachyon:tachyon 3.sparkR:sparkR 所有内容请点击:所有内 ...

  6. Dojo Chart之经常使用统计图

    非常多做web的都知道,在非常多web系统中会涉及到一些统计图.比如饼状图,柱状图.趋势图.以及叠加图等.提到这儿,做web的都非常熟悉的,jquery的highcharts就能搞定全部的涉及到统计图 ...

  7. J2SE基础:2.对象的创建与使用

    1:參数传递的值传递与引用传递 A:值传递:基本数据类型传递都是值传递 B:引用传递(地址传递):对象数据类型都是引用传递. 2:类变量与成员变量(实例变量,对象变量) 类变量:通过类名调用,类变量被 ...

  8. OpenCASCADE解非线性方程组

    OpenCASCADE解非线性方程组 eryar@163.com Abstract. 在科学技术领域里常常提出求解非线性方程组的问题,例如,用非线性函数拟合实验数据问题.非线性网络问题.几何上的曲线曲 ...

  9. AFNetworking 取消请求

    取消单个操作: AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request] ...

  10. JAVA配置环境