찾다
웹 프론트엔드HTML 튜토리얼学习React系列1-React-tutorial全解析_html/css_WEB-ITnose

React-tutorial例子全解析

Talk is cheap,Show me the code

近些时间一直在关注React,关于 如何学习React可以参照链接的文章自行制定计划。千里之行,始于足下。本文是React官方的教程上的一个例子,通过详细地学习,从中收获不少,特此做了笔记,与大家共享交流进步。

起步

  1. 下载 例子,然后进行解压

  2. 由于采用的node环境,因此下载解压之后,只需在所在目录运行

    npm installnode server.js
  3. 采用默认端口设置,只需打开浏览器,访问 http://localhost:3000/

目录结构说明

react-tutorial

--node_modules    --body-parser:express中间件,用于接收和解析json数据    --express:express框架--public    --css        --base.css:基本样式文件    --scripts        -- example.js:React应用js文件    index.html:基本的HTML结构--.editorconfig:用于在不同的编辑器中统一编辑风格(文件编码)的配置文件--.gitignore:git相关配置文件--app.json:web app的相关信息--comments.json:上传的评论数据--LICENSE:项目代码使用协议--package.json:项目所依赖的包,npm install的安装包的配置文件--README.md:项目说明书,里面有使用说明--requirements.txt:不清楚--server.js:服务器端的js代码

App功能

此项目构建了一个简单的应用,如图所示

服务器端

服务器端的功能还是相对简单的,通过代码注释的形式来分析

  1. 导入了依赖的模块

    var fs = require('fs');  //读写文件var path = require('path'); //路径var express = require('express'); //express框架var bodyParser = require('body-parser'); //中间件
  2. 生成app,并且进行配置

    //获取comments.json文件的路径var COMMENTS_FILE = path.join(__dirname, 'comments.json');//设置端口app.set('port', (process.env.PORT || 3000));//设置静态文件的文件目录路径app.use('/', express.static(path.join(__dirname, 'public')));//启用bodyParser中间件接收请求,并且接收并解析json数据app.use(bodyParser.json());app.use(bodyParser.urlencoded({extended: true}));
  3. 设置响应头部信息

    app.use(function(req, res, next) {    //允许跨域 CORS    res.setHeader('Access-Control-Allow-Origin', '*');    //缓存设置    res.setHeader('Cache-Control', 'no-cache');    next();});
  4. 设置get请求url对应的处理函数(获取评论json数据)

    app.get('/api/comments', function(req, res) {    //读取comments.json文件,并且解析为json数据    fs.readFile(COMMENTS_FILE, function(err, data) {        if (err) {          console.error(err);          process.exit(1);        }        //读取成功后,返回        res.json(JSON.parse(data));    });});
  5. 设置post请求url对应的处理函数(提交评论数据)

    app.post('/api/comments', function(req, res) {    //先读取comments.json文件    fs.readFile(COMMENTS_FILE, function(err, data) {        if (err) {          console.error(err);          process.exit(1);        }        //将文件内容解析为json数据        var comments = JSON.parse(data);        //获取新评论        var newComment = {          id: Date.now(),          author: req.body.author,          text: req.body.text,        };        //添加json数组中        comments.push(newComment);        //将json数据写回到comments.json文件中,并且返回全部的评论数据         fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) {              if (err) {                console.error(err);                process.exit(1);              }              res.json(comments);        });    });});
  6. 启动,监听端口

    app.listen(app.get('port'), function() {  console.log('Server started: http://localhost:' + app.get('port') + '/');});

web端

web端核心在于 example.js文件,结合官网的资料,我们对这个应用进行分析,学习如何构建一个简单的react应用。

组件结构

React践行了 Web Components的理念,依照组件化的开发方式,我们来分析这个应用的组件结构(如图所示):

即是:

-- CommentBox    -- CommentList        -- Comment    -- CommentForm

组件之间的关系图为:

组件Comment

如上述的结构图,我们从最底层开始编写组件 Comment,这个组件需要做两件事情

  1. 接收上层组件 CommentList传递的数据,动态渲染虚拟DOM节点,则从 props中读取数据

    //评论人{this.props.author}//评论的内容{this.props.children}
  2. 由于评论是支持MarkDown语法的,因此需要使用第三放库 marked对用户输入的内容进行处理。

    var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
  3. 此外,输出的内容要解析为HTML,而在默认情况下,基于预防XSS攻击的考虑,React对输出的内容是不解析为HTML的。此时,需要利用到特殊的属性 dangerouslySetInnerHTML,要将内容放到一个对象的 _html属性中,然后将这个对象赋值给 dangerouslySetInnerHTML属性

    var html = {_html:"输出的html内容"};<span dangerouslySetInnerHTML={html} />
var Comment = React.createClass({    rawMarkup : function() {        var rawMarkup =  marked(this.props.children.toString(),{sanitize:true});        return {_html : rawMarkup}; //React的规则,会读取这个对象的_html内容,    },    render : function() {        return (            <div className="comment">                <h2 id="this-props-author">                    {this.props.author}                </h2>                <span  dangerouslySetInnerHTML={this.rawMarkup()} />            </div>        );    }});

组件CommentList

组件 CommentList需要做的就是接收上一层组件 CommentBox传递过来的数据,然后根据数据生成多个子组件 Comment

var CommentList = React.createClass({    render : function() {        var commentNodes = this.props.data.map(function(comment){            return (                <Comment author={comment.author} key={comment.id}>                    {comment.text}                </Comment>            );        });        return (            <div className="commentList">                {commentNodes}            </div>        );    }})

在生成子组件 Comment时,将每个子组件的key属性设置为 comment.id,这是因为 key是一个可选的唯一标识符,通过它可以给组件设置一个独一无二的键,并确保它在一个渲染周期中保持一致,使得React能够更加智能地决定应该重用一个组件,还是销毁并重新创建一个组件,进而提升渲染性能。

组件CommentForm

组件 CommentForm需要做的就是两件事情

  1. 管理自身的状态 this.state(即表单中输入的评论人和评论内容)

    1. 当表单输入发生变化时

    2. 当表单提交时

  2. 当submit事件触发时,调用上一层组件 CommentBox的事件处理函数,改变组件 CommentBox的状态。

var CommentForm = React.createClass({    getInitialState : function() {        //设置初始状态,        return {author:'',text:''};    },    handleAuthorChange : function(e) {        this.setState({            author : e.target.value        });    },    handleTextChange : function(e) {        this.setState({            text : e.target.value        });    },    handleSubmit : function(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:''});    }});

在这里有一个值得注意的点,那就是抽象的自定义事件 commentSubmit和真实的事件 submit之间的联系,这是一个相当实用的技巧,在接下来的章节可以看到是如何实现的。

组件CommentBox

作为整个应用的顶层组件, CommentBox需要做的事情有:

  1. 从服务器端请求已有的评论数据

  2. 将新的评论数据上传到服务器

  3. 管理自身的状态,根据状态对视图进行渲染(状态改变的示意图如下)

var CommentBox = React.createClass({    getInitialState : function(){        return {data : []};    },    loadCommentsFromServer : function() {        //使用了jQuery的Ajax        $.ajax({            url : this.props.url,            dataType : 'json',            cache : false,            success : function(data) {                this.setState({data:data});            }.bind(this),            error : function(xhr,status,err){                console.err(this.props.url,status,err.toString());            }.bind(this)        });    },    componentDidMount : function() {        /*        这个方法属于React组件生命周期方法,在render方法成功调用并且真实的DOM        已经渲染之后,调用此方法,这个方法发送json数据请求,并且设置一个定时器        ,每隔一段时间就向服务器请求数据        */        this.loadCommentsFromServer();        setInterval(this.loadCommentsFromServer,this.props.pollInterval);    },    handleCommentSubmit : function(comment) {        /*        这个方法也是比较有意思:        1. 自定义了一个commentSubmit事件,并且此方法作为该事件的处理函数。        2. 此方法是在子组件CommentForm的submit事件处理函数中调用        */        var comments = this.state.data;        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.err(this.props.url,status,err.toString());            }.bind(this)        });    },    render : function() {        return (            <div className="commentBox">                <h1 id="Comments">Comments</h1>                <CommentList data={this.state.data} />                <CommentForm onCommentSubmit={this.handleCommentSubmit} />            </div>        );    }});

最后,只需将组件 CommentBox挂载到真实的DOM节点上,就可以看到效果了

ReactDOM.render(    <CommentBox url="/api/comments" pollInterval={2000} />,    document.getElementById('content'));
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
HTML의 역할 : 웹 컨텐츠 구조HTML의 역할 : 웹 컨텐츠 구조Apr 11, 2025 am 12:12 AM

HTML의 역할은 태그 및 속성을 통해 웹 페이지의 구조와 내용을 정의하는 것입니다. 1. HTML은 읽기 쉽고 이해하기 쉽게하는 태그를 통해 컨텐츠를 구성합니다. 2. 접근성 및 SEO와 같은 시맨틱 태그 등을 사용하십시오. 3. HTML 코드를 최적화하면 웹 페이지로드 속도 및 사용자 경험이 향상 될 수 있습니다.

HTML 및 코드 : 용어를 자세히 살펴 봅니다HTML 및 코드 : 용어를 자세히 살펴 봅니다Apr 10, 2025 am 09:28 AM

"Code"는 "Code"BroadlyIncludeLugageslikeJavaScriptandPyThonforFunctureS (htMlisAspecificTypeofCodeFocudecturecturingWebContent)

HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구Apr 09, 2025 am 12:12 AM

HTML, CSS 및 JavaScript는 웹 개발의 세 가지 기둥입니다. 1. HTML은 웹 페이지 구조를 정의하고 등과 같은 태그를 사용합니다. 2. CSS는 색상, 글꼴 크기 등과 같은 선택기 및 속성을 사용하여 웹 페이지 스타일을 제어합니다.

HTML, CSS 및 JavaScript의 역할 : 핵심 책임HTML, CSS 및 JavaScript의 역할 : 핵심 책임Apr 08, 2025 pm 07:05 PM

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

HTML은 초보자를 위해 쉽게 배우나요?HTML은 초보자를 위해 쉽게 배우나요?Apr 07, 2025 am 12:11 AM

HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML의 시작 태그의 예는 무엇입니까?HTML의 시작 태그의 예는 무엇입니까?Apr 06, 2025 am 12:04 AM

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

메뉴에서 점선 분할 효과의 중심 정렬을 달성하기 위해 CSS의 Flexbox 레이아웃을 사용하는 방법은 무엇입니까?메뉴에서 점선 분할 효과의 중심 정렬을 달성하기 위해 CSS의 Flexbox 레이아웃을 사용하는 방법은 무엇입니까?Apr 05, 2025 pm 01:24 PM

메뉴에서 점선 분할 효과를 설계하는 방법은 무엇입니까? 메뉴를 설계 할 때는 일반적으로 접시 이름과 가격 사이에 왼쪽과 오른쪽을 정렬하는 것이 어렵지 않지만 점선 또는 중간의 점은 어떻습니까?

온라인 코드 편집기는 코드 입력을 구현하는 데 사용하는 HTML 요소는 무엇입니까?온라인 코드 편집기는 코드 입력을 구현하는 데 사용하는 HTML 요소는 무엇입니까?Apr 05, 2025 pm 01:21 PM

웹 코드 편집기의 HTML 요소 분석 많은 온라인 코드 편집기를 사용하면 사용자가 HTML, CSS 및 JavaScript 코드를 입력 할 수 있습니다. 최근에 누군가가 제안했습니다 ...

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경