一步一步写web之react实战(四-评论框)

昨天完成了初始化,顺便看了下源代码,今天预计写出一个示例评论框的,可惜最后卡在与服务端交互这里,是时候学习一波服务端知识了,知识这个节骨点有点不好合适,只能想着折中的办法吧,其实就差一个webapp没搞过了,好可惜,不然自己搞他一套完整的出来。争取react系列写完了学习后端,以后写分享就是前后通吃,哈哈!

还是开始吧,附上教程:http://reactjs.cn/react/docs/tutorial-zh-CN.html。因为教程下载的代码可以直接运行,我就没有用他的。在昨天的初始化项目里修改。教程里的代码都是ES5的语法,我有点不习惯,就只做参考,我这里就都转化成ES6了,大家想了解的话可以和教程作对比。

首先教程在body中引用script,在example.js里修改代码。而我们初始化的入口在App.js。我们就从这里入手。第一步先建一个CommentBox.js。在里面定义一个类

import React, {Component} from 'react';

export default class CommentBox extends Component {
    render() {
        return (
            <div className="commentBox">
                <h1>我是CommentBox</h1>
            </div>
        );
    }
}
然后在App.js里引用,引用也很简单,就是在头部用import导入,在render的return中把他当成普通的自闭合标签一样找个地方放一下就行。不会的去git上看代码吧,看一次就会。下面接着写,教程从“你的第一个组件”开始每个code头都加了

// tutorial1.js
很多这种注释,只是数字在变。然而,这并不是我们需要建的文件名,不是说一个tuorial.js就是一个文件,写文章的都是大牛,这点小问题在他们看了就像吃饭需要筷子一样,不需要说的,也或者他们自己认为都在一个文件里,我只是用注释分区下方便你们阅读而已。我的代码呢就争取一个模块一个文件把它们区分开。

按照教程,我的代码最终分在这四个文件里。文章中都是React.creatClass创建类,而我用的是下面这种形式

import React, {Component} from 'react';
import Comment from './Comment';

export default class CommentList extends Component {

    render() {
        let commentNodes = this.props.data.map((comment)=>{
            return (
                <Comment author={comment.author} key={comment.id}>
                    {comment.text}
                </Comment>
            );
        });
        return <div className="CommentList">
            {commentNodes}
        </div>;
    }
}
这种创建类的方式默认就导出了,一个类一个文件,我觉得这样比较好。当然,定义变量我也尽量都用let而不是var。其实大家也可以把它们写在一个文件里,我也试了下可行,只是我还是喜欢分开,在一起的代码我注释了没有删
import React, {Component} from 'react';
import Comment from './Comment';

export default class CommentList extends Component {

    render() {
        let commentNodes = this.props.data.map((comment)=>{
            return (
                <Comment author={comment.author} key={comment.id}>
                    {comment.text}
                </Comment>
            );
        });
        return <div className="CommentList">
            {commentNodes}
        </div>;
    }
}

// class CommentForm extends Component{
//     constructor(props){
//         super(props);
//     }
//
//     render(){
//         return <div className="commentForm">
//             Hello, world! I am a CommentForm.
//         </div>;
//     }
// }
//
// class CommentBox extends Component{
//     constructor(props){
//         super(props);
//         this.state={
//             displayName: 'CommentBox',
//         }
//     }
//
//     render(){
//         return (
//             React.createElement('div', {className: 'commentBox'},
//                 "Hello, world! I am a CommentBox."
//             )
//         );
//     }
// }
// export {CommentList, CommentForm, CommentBox};
这就是没分开的情况,把export default去掉,在最后统一export即可。

每个类一个文件的形式,这样对照教程就明朗了,教程中修改了什么我们就去对应的文件里改什么。还有一点,我的每个函数都进行了绑定,有两种方法

export default class Comment extends Component{
    constructor(props){
        super(props);
        this.rawMarkup=this.rawMarkup.bind(this); //这种绑定方式对应下面 11-15行
    }

    rawMarkup() {
        let md = new Remarkable();
        let rawMarkup = md.render(this.props.children.toString());
        return { __html: rawMarkup};
    }

    // //下面的箭头函数等同于第( 8 + 11-15 )行的效果
    // rawMarkup = ()=>{
    //     let md = new Remarkable();
    //     let rawMarkup = md.render(this.props.children.toString());
    //     return { __html: rawMarkup};
    // }

    render(){
        // var md = new Remarkable();
        return <div className="comment">
            <h2 className="commentAuthor">
                {this.props.author}
            </h2>
            <span dangerouslySetInnerHTML={this.rawMarkup()} />
        </div>
    }
}

上面这段代码用了两种绑定,第一个就是在构造函数constructor中用this绑定,第二种就是注释掉的那几行代码,用箭头函数绑定。两种绑定引用是相同的都是this.rawMarkup()。

最终代码卡在与服务器交互了,从服务端获取数据。我想自己研究下node.js自己写一个服务器的,可是最近时间很紧,以后得把这一块只是空白补上,不能留遗憾!还是附代码吧,这几天争取看下前后端分离的框架,不能像今天这样,遇到服务端就卡主了。附上今天的页面展示与代码。

https://github.com/dwenb/react-learning/commits/master

  罪过!!!忘了这一篇代码忘了传了,虽然是不完整的,引以为戒,下不为例!




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基本的 `webpack.config.js` 文件,用于将 React Native Web 应用程序打包为 Web 应用程序: ```javascript const path = require('path'); const webpack = require('webpack'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader'] }, { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, resolve: { extensions: ['*', '.js', '.jsx'] }, plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { contentBase: './dist', hot: true } }; ``` 其中,`entry` 表示入口文件,`output` 表示输出文件路径和文件名。`module` 中的 `rules` 字段表示转换规则。在这个例子中,我们使用了 `babel-loader` 来将 ES6/JSX 语法转换为浏览器可识别的语法。我们还使用了 `style-loader` 和 `css-loader` 来处理 CSS 文件。`resolve` 字段用于指定可以省略的后缀名,以便在导入文件时更加方便。`plugins` 中我们使用了 `HotModuleReplacementPlugin` 来启用热重载。 最后,在 `devServer` 中,我们指定了 Webpack Dev Server 的配置。`contentBase` 表示服务器启动时的根目录,`hot` 表示启用热重载。 当然,还需要配置 `.babelrc` 文件来指定 Babel 转换规则。例如: ```json { "presets": [ "@babel/preset-env", "@babel/preset-react", "module:metro-react-native-babel-preset" ] } ``` 其中,`@babel/preset-env` 和 `@babel/preset-react` 分别用于转换 ES6 和 JSX 语法,`module:metro-react-native-babel-preset` 则是为了让 React Native Web 应用程序能够在 Webpack 中正确地解析依赖项。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值