博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用TypeScipt和AMD模块化理念实现React官方教程(五)提交和更新数据
阅读量:4589 次
发布时间:2019-06-09

本文共 7712 字,大约阅读时间需要 25 分钟。

添加新的评论

现在开始创建表单,我们的CommentForm 组件会需要用户填写他们的姓名和评论内容并发送一个请求到服务器保存评论。

修改CommentForm.tsx 如下:

/// 
export =CommentForm;class CommentForm extends React.Component
{
render() { return (
); }}

控制组件

使用传统DOM,渲染 input 元素并由浏览器管理状态(它渲染的值)。因此,实际DOM的状态会跟组件的状态不同。视图的状态同组件不同是不理想的。在React中,组件总是代表着视图的状态,不仅仅在初始化的时候。

因此,我们会使用 this.state 在用户键入时保存用户的输入。我们给初始 state 定义了两个属性 authortext 并设置成空字符串。在我们的 <input> 元素,我们设置 value prop 反应组件的 state 并附上 onChange 处理它们。 这些 <input> 元素带有 value 设置的我们叫它们为控制组件。

/// 
export =CommentForm;interface CommentFormState {
author: string; text: string;}class CommentForm extends React.Component
{
public state: CommentFormState; constructor(props) { super(props); this.state = { author: '', text: '' }; } handleAuthorChange = (e) => { this.setState({ author: e.target.value, text: this.state.text }); } handleTextChange = (e) => { this.setState({ author: this.state.author, text: e.target.value }); } render() { return (
); }}

请特别注意事件处理程序跟官方教程的不同之处。

从程序中可以看出,为了使state和组件保持一致,使用了onChange。

事件

React使用驼峰命名规则给组件绑定事件处理。我们将 onChange 绑定到两个 <input> 元素。现在,当用户输入文本时,绑定的处理函数触发回调,组件的 state 将会更改。随后,input元素的渲染值会更新反应当前组件的状态。

提交表单

现在让表单进行互动,当用户提交表单后,我们将清除它,提交一个请求到服务器,并刷新评论列表。开始,让我们侦听表单提交事件并清除它。

/// 
export =CommentForm;interface CommentFormState { author: string; text: string;}class CommentForm extends React.Component
{
public state: CommentFormState; constructor(props) { super(props); this.state = { author: '', text: '' }; } handleAuthorChange = (e) => { this.setState({ author: e.target.value, text: this.state.text }); } handleTextChange = (e) => { this.setState({ author: this.state.author, text: e.target.value }); } handleSubmit=(e)=>{ e.preventDefault(); var author = this.state.author.trim(); var text = this.state.text.trim(); if (!text || !author) { return; } // TODO: send request to the server this.setState({ author: '', text: '' }); } render() { return (
); }}

我们绑定 onSubmit 来处理表单,当表单输入有效后提交并请除清单字段。请用 preventDefault() 是为了阻止浏览器缺省的提交表单动作。

用回调函数作为props

当用户提交一个评论时,我们需要刷新评论列表包含新的这个评论。在CommentBox 中放置 所有的逻辑是合适的,因为CommentBox 包含了代表当前评论列表的状态。

我们需要将数据从子组件传回到父组件中。我们在父组件的 render 方法中通过传递一个新的回调函数(handleCommentSubmit )到子组件。绑定到子组件的 onCommentSubmit 事件。无论什么时候触发,回调函数都会被调用。

/// 
///
import CommentList = require("./CommentList");import CommentForm = require("./CommentForm");export =CommentBox;interface CommentBoxProps { url: string; pollInterval: number;}interface CommentBoxState { data: any;}class CommentBox extends React.Component
{
public state: CommentBoxState; constructor(props: CommentBoxProps) { super(props); this.state = { data: [] }; } loadCommentsFromServer() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); } handleCommentSubmit = (comment) => { //Todo:提交到服务器并刷新列表 } componentDidMount() { //this.loadCommentsFromServer(); //setInterval(this.loadCommentsFromServer, this.props.pollInterval); //setInterval(() => this.loadCommentsFromServer, this.props.pollInterval); setInterval(() => this.loadCommentsFromServer(), this.props.pollInterval); } render() { return (

评论

); }}

当用户提交表单时,让我们从CommentForm 中调用回调函数。

/// 
export =CommentForm;interface CommentFormState { author: string; text: string;}class CommentForm extends React.Component
{
public state: CommentFormState; constructor(props) { super(props); this.state = { author: '', text: '' }; } handleAuthorChange = (e) => { this.setState({ author: e.target.value, text: this.state.text }); } handleTextChange = (e) => { this.setState({ author: this.state.author, text: e.target.value }); } handleSubmit=(e)=>{ e.preventDefault(); var author = this.state.author.trim(); var text = this.state.text.trim(); if (!text || !author) { return; } this.props.onCommentSubmit({ author: author, text: text }); this.setState({ author: '', text: '' }); } render() { return (
); }}

现在回调函数已经就绪,我们现在要做的只是提交到服务器并刷新列表:

优化:提前更新

我们的应用现在已经功能完备了,但是新添加的评论需要等待对服务器的请求完成后才会出现在列表中, 这样感觉会慢一点。我们可以提前将这条评论放到列表中让应用感觉更快。

/// 
///
import CommentList = require("./CommentList");import CommentForm = require("./CommentForm");export =CommentBox;interface CommentBoxProps { url: string; pollInterval: number;}interface CommentBoxState { data: any;}class CommentBox extends React.Component
{
public state: CommentBoxState; constructor(props: CommentBoxProps) { super(props); this.state = { data: [] }; } loadCommentsFromServer() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); } handleCommentSubmit = (comment) => { var comments = this.state.data; // Optimistically set an id on the new comment. It will be replaced by an // id generated by the server. In a production application you would likely // not use Date.now() for this and would have a more robust system in place. comment.id = Date.now(); var newComments = comments.concat([comment]); this.setState({ data: newComments }); $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: comment, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { this.setState({ data: comments }); console.error(this.props.url, status, err.toString()); }.bind(this) }); } componentDidMount() { //this.loadCommentsFromServer(); //setInterval(this.loadCommentsFromServer, this.props.pollInterval); //setInterval(() => this.loadCommentsFromServer, this.props.pollInterval); setInterval(() => this.loadCommentsFromServer(), this.props.pollInterval); } render() { return (

评论

); }}

OK,教程到此结束,因为不是专业写作,肯定有很多不足之处,欢迎各种拍砖和讨论。等时间充裕时我再整理一下整个教程,有可能的话在GitHub上把所有源代码上传以便大家直接开箱使用。

转载于:https://www.cnblogs.com/eeeeee/p/5204806.html

你可能感兴趣的文章
java线程详解(三)
查看>>
9.17模拟赛2.0
查看>>
洛谷 P3225 [HNOI2012]矿场搭建
查看>>
orcad找不到dll
查看>>
各种排序算法的性能特点
查看>>
LET IT BE
查看>>
在线帮助你修改图片背景的工具 - Clipping Magic
查看>>
BizTalk动手实验(十三)EDI解决方案开发配置
查看>>
初学github
查看>>
iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)
查看>>
extjs 下载文件 关键前后端代码
查看>>
.NET 4.0 兼容 .NET 2.0 的方法
查看>>
1001 Maximum Multiple(2018 Multi-University Training Contest 1)
查看>>
对Java对象的认识与理解
查看>>
python——父类与子类的一些说明
查看>>
2019年3月3日 2018-2019-2 20189205《移动平台应用开发实践》第二周作业
查看>>
MySQL 性能优化--优化数据库结构之优化数据类型
查看>>
软件工程之软件需求分析
查看>>
Electron简介和安装使用
查看>>
Improving Visual C++ Debugging with Better Data Display
查看>>