使用 React 和 Next.js 构建博客

标签: | 发表时间:2022-04-11 16:27 | 作者:
出处:https://blog.51cto.com

Next.js是由 Vercel 创建和维护的基于 React 的应用程序框架。本教程将从零开始学习如何使用 Next.js构建一个小型的博客网站:

  • 基本页面创建
  • Markdown文件生成的动态路由
  • 静态生成(在构建时渲染)
  • 服务器端渲染(在请求时渲染)

文章涉及的代码仓库地址: https://github.com/QuintionTang/react-blog

Next.js 适合博客吗?

本教程将通过创建一个简单的博客来展示 Next.js功能,那么 Next.js适合这样的博客的开发吗?先来了解一下一般博客都需要什么?

nextjsbanner.png

  • WordPress是一个内容管理系统 (CMS),它为三分之一的网站提供支持,通过在每次请求时将可编辑的数据库内容渲染到 PHP 模板中来为页面提供服务。它非常适合定期更新的内容,但性能、安全性和数据备份需要一定的自定义设置。

  • 静态站点生成器 (SSG),例如 EleventyGatsby创建预渲染文件,无需服务器端或数据库即可快速构建静态站点,在版本控制、性能和安全性都非常出色,但构建步骤和以开发人员为中心的过程可能会减慢发布速度,尤其是在大型网站上。

Next.js是一个基于 React 的应用程序框架,它几乎没有特定于博客功能。但是,它可以提供了一种实现机制:

  1. 在可能的情况下, Next.js生成静态内容,如 SSG,这些页面加载速度非常快,可以被搜索引擎快速收录,并且可以在任何有或没有 JavaScript 的设备上阅读。
  2. 在第一次加载后, Next.js应用程序的行为类似于单页应用程序 (SPA),后续页面和代码会以渐进式下载,无需刷新整页。
  3. Next.js为每个请求提供服务器端渲染 (SSR),为个人用户提供实时 CMS 更新或自定义内容变得更加容易。

如果网站可能会从基本博客迭代为更复杂的网站,例如在线商店、新闻聚合服务、社交媒体平台等,可以考虑使用 Next.js

开始

本教程正在构建的内容,可以在 GitHub 上找到完整的代码。可以通过在终端中输入以下命令,在 WindowsmacOSLinux上下载、安装和启动它:

      git clone [email protected]:QuintionTang/react-blog.git
cd react-blog
npm i
npm run dev

然后在浏览器中输入 localhost:3000打开主页。

从头开始构建

Next.js提供了一个 create-next-app工具来快速开始使用应用程序模板。本教程将展示如何从头开始构建站点:如添加静态资源或者页面。

安装 Next.js 和 React

与其他 Node.js或者 VUE 项目一样,首先创建一个目录并初始化 package.json文件:

      mkdir react-blog
cd react-blog
npm init

然后安装 Next.jsReact作为依赖项:

      npm install next react react-dom --save

添加开发构建脚本设置,如下所示,在 package.json文件的 scripts属性中添加:

      "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
}
创建第一个页面

Next.js有一个基于文件系统的路由器。在项目的 pages目录中创建的任何 React 组件文件都会自动呈现为一个页面。

要创建一个页面,需要在 pages目录中添加一个 index.js文件。将以下代码添加到 ./pages/index.js文件中,返回 JSX代码的功能性 React 组件:

      export default function Home() {
    return (
        <>
            Next.js 博客网站
            <p>
                这个博客网站将使用 <a rel="nofollow" href="https://nextjs.org/">Next.js</a>。
            </p>
        </>
    );
}

JSX 必须在单个包含元素(例如 &lt;div&gt;)中返回。 &lt;&gt; ... &lt;/&gt;表示法定义了一个文档片段,因此不需要额外的容器。

要启动 Next.js开发服务器,从项目根目录在终端中运行 npm run dev(可以使用 npx next dev),然后在浏览器中打开 http://localhost:3000/

WechatIMG119622222.png

Next.js已经确定页面可以预渲染,所以它在开发模式下显示一个 闪电图标

可以在自动路由的页面目录中创建类似的文件,如下:

  • pages/index.js用于呈现博客主要
  • pages/about.js呈现一个 /about页面
增加链接

在 JSX 代码中使用标准 HTML &lt;a&gt;标签创建指向另一个页面的超链接。如果该页面位于同一个 Next.js站点内,浏览器将会刷新整个页面。可以使用 next/link中的 &lt;Link&gt;组件实现页面跳转。在根页面 /index.js上创建指向 /about页面的链接,代码如下:

      import Link from "next/link";
export default function Home() {
    return (
        <>
            Next.js 博客网站
            <p>
                这个博客网站将使用 <a rel="nofollow" href="https://nextjs.org/">Next.js</a>。
            </p>
            <p>
                更多内容请点击{" "}
                <Link href="/about">
                    <a>关于我们...</a>
                </Link>
            </p>
        </>
    );
}

当点击 关于我们...链接时, Next.js将使用 Ajax请求下载 /about的内容一次并缓存,然后再页面中呈现。

增加 <head> 元素

可以使用 next/head中的 &lt;Head&gt;组件来更改页面标题和元标记,如下:

      import Head from "next/head";
import Link from "next/link";
export default function Home() {
    return (
        <>
            <Head>
                <title>Next.js网站</title>
                <meta
                    name="description"
                    content="这是一个由 Next.js 驱动的网站"
                />
            </Head>
            Next.js 博客网站
            <p>
                这个博客网站将使用 <a rel="nofollow" href="https://nextjs.org/">Next.js</a>。
            </p>
            <p>
                更多内容请点击{" "}
                <Link href="/about">
                    <a>关于我们...</a>
                </Link>
            </p>
        </>
    );
}

点击浏览器查看源代码,可以看到相关 HTML 标签。

增加静态资源

public目录用于存放静态资源,如图标、 robots.txt或其它更新频率低的文件。可以增加自己的文件或从初始项目存储库复制 favicon.ico和图像子目录。

创建模板

Next.js使用 React 组件来实现模板化,接下来项目根目录下创建一个新的 components文件夹,然后添加 layout.js来定义一个新的 &lt;Layout&gt;组件:

      import Header from "./header";
import Footer from "./footer";

export default function Layout({ children, title }) {
    return (
        <>
            <Header title={title} />
            <main>{children}</main>
            <Footer />
        </>
    );
}

任何使用此组件的页面都会传递一个 props对象,该对象包含作为子值 children的内容。 &lt;Layout&gt;还将引用了另外两个组件,分别是 component/header.js中的 &lt;Header&gt;,主要呈现一个 &lt;header&gt;,包含主页链接、内联 SVG Logo和 默认为 /images/header.jpg的图像:

      import Link from "next/link";

export default function Header({ title }) {
    const headerImg = "/images/" + (title || "header.jpg");

    return (
        <header>
            <p className="logo">
                <Link href="/">
                    <a>
                        <svg
                            xmlns="http://www.w3.org/2000/svg"
                            viewBox="0 0 20 20"
                            width="50"
                            height="50"
                        >
                            <path d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z"></path>
                        </svg>
                        Next.js 博客
                    </a>
                </Link>
            </p>

            <figure>
                <img
                    src={headerImg}
                    height="80"
                    alt="decoration"
                />
            </figure>
        </header>
    );
}

第二个组件是 component/footer.js中的 &lt;Footer&gt;,呈现 &lt;footer&gt;内容,其中包含指向 GitHub 存储库和内联 SVG 的链接:

      export default function Footer() {
    return (
        <footer>
            <p className="github">
                <a rel="nofollow" href="https://github.com/QuintionTang/react-blog">
                    <svg
                        xmlns="http://www.w3.org/2000/svg"
                        viewBox="0 0 512 512"
                        width="50"
                        height="50"
                    >
                        <path d="M256 32C132.3 32 32 134.9 32 261.7a229.3 229.3 0 00153.2 217.9 17.6 17.6 0 003.8.4c8.3 0 11.5-6.1 11.5-11.4l-.3-39.1a102.4 102.4 0 01-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8 11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0025.6-6c2-14.8 7.8-24.9 14.2-30.7-49.7-5.8-102-25.5-102-113.5 0-25.1 8.7-45.6 23-61.6a84.6 84.6 0 012.2-60.8 18.6 18.6 0 015-.5c8.1 0 26.4 3.1 56.6 24.1a208.2 208.2 0 01112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.6 18.6 0 015 .5 84.6 84.6 0 012.2 60.8 90.3 90.3 0 0123 61.6c0 88.2-52.4 107.6-102.3 113.3 8 7.1 15.2 21.1 15.2 42.5 0 30.7-.3 55.5-.3 63 0 5.4 3.1 11.5 11.4 11.5a19.4 19.4 0 004-.4A229.2 229.2 0 00480 261.7C480 134.9 379.7 32 256 32z" />
                    </svg>
                    https://github.com/QuintionTang/react-blog
                </a>
            </p>
        </footer>
    );
}

接下来更新 pages/index.js,将使用自定义的 &lt;Layout&gt;组件:

      import Layout from "../components/layout";
import Head from "next/head";
import Link from "next/link";
export default function Home() {
    return (
        <Layout>
            <Head>
                <title>Next.js网站</title>
                <meta
                    name="description"
                    content="这是一个由 Next.js 驱动的网站"
                />
            </Head>
            Next.js 博客网站
            <p>
                这个博客网站将使用 <a rel="nofollow" href="https://nextjs.org/">Next.js</a>。
            </p>
            <p>
                更多内容请点击{" "}
                <Link href="/about">
                    <a>关于我们...</a>
                </Link>
            </p>
        </Layout>
    );
}

然后对 pages/about.js和创建的任何其他页面执行相同操作。

      import Layout from "../components/layout";
import Head from "next/head";

export default function Home() {
    return (
        <Layout title="share.png">
            <Head>
                <title>关于我们</title>
            </Head>

            关于我们
            <p>
                DevPoint 是 WEB
                开发的分享中心,用自己的热情来分享互联网的点滴,以此激励自己加强学习提升自我。
            </p>
        </Layout>
    );
}

更新后的效果如下:

1642841913123.jpg

使用动态路由查看博客内容

使用 JSX 创建内容并不是特别实用,尤其是对于常规博客文章,对于开发者比较喜欢 Markdown 的方式写博客。Next.js 可以使用任何来源创建页面。这些可以在构建时静态生成,并使用动态路由将数据映射到 URL。

在继续之前,先来创建一个文章目录,用于存放博客的 Markdown 文件。例如: articles/article-01.md

      ---
title: 使用 React 和 Next.js 构建博客
description: Next.js 是由 Vercel 创建和维护的基于 React 的应用程序框架。本教程将从零开始学习如何使用 Next.js 构建一个小型的博客网站。
date: 2022-01-22
tags:
    - HTML
    - CSS
    - REACT
---

使用 React 和 Next.js 构建博客

## 摘要

Next.js 是由 Vercel 创建和维护的基于 React 的应用程序框架。本教程将从零开始学习如何使用 Next.js 构建一个小型的博客网站。

本教程将通过创建一个简单的博客来展示 Next.js 功能,那么 Next.js 适合这样的博客的开发吗?先来了解一下一般博客都需要什么?

-   WordPress 是一个内容管理系统 (CMS),它为三分之一的网站提供支持,通过在每次请求时将可编辑的数据库内容渲染到 PHP 模板中来为页面提供服务。它非常适合定期更新的内容,但性能、安全性和数据备份需要一定的自定义设置。
-   静态站点生成器 (SSG),例如 Eleventy 或 Gatsby 创建预渲染文件,无需服务器端或数据库即可快速构建静态站点,在版本控制、性能和安全性都非常出色,但构建步骤和以开发人员为中心的过程可能会减慢发布速度,尤其是在大型网站上。

Next.js 是一个基于 React 的应用程序框架,它几乎没有特定于博客功能。但是,它可以提供了一种实现机制:

1. 在可能的情况下,Next.js 生成静态内容,如 SSG,这些页面加载速度非常快,可以被搜索引擎快速收录,并且可以在任何有或没有 JavaScript 的设备上阅读。
2. 在第一次加载后,Next.js 应用程序的行为类似于单页应用程序 (SPA),后续页面和代码会以渐进式下载,无需刷新整页。
3. Next.js 为每个请求提供服务器端渲染 (SSR),为个人用户提供实时 CMS 更新或自定义内容变得更加容易。
   如果网站可能会从基本博客迭代为更复杂的网站,例如在线商店、新闻聚合服务、社交媒体平台等,可以考虑使用 Next.js。

内容的模板以 ---来定义博客的标题、发布时间等元数据, ---后面的为博客的正文。接下来需要安装解析内容的依赖,包括: front-matterremarkremark-html,执行一下命令:

      npm install front-matter remark remark-html --save

要读取和解析 Markdown 文件,需要添加相关逻辑,代码所在文件 libs/posts-md.js

      import { promises as fsp } from "fs";
import path from "path";
import fm from "front-matter";
import { remark } from "remark";
import remarkhtml from "remark-html";
import * as dateformat from "./dateformat";

const fileExt = "md";

// 获取文件夹相对路径
function absPath(dir) {
    return path.isAbsolute(dir) ? dir : path.resolve(process.cwd(), dir);
}

/**
 * 获取文件夹中 Markdown 文件名列表,以数组形式返回
 * @param {*} dir
 * @returns
 */
export async function getFileIds(dir = "./") {
    const loc = absPath(dir);
    const files = await fsp.readdir(loc);

    return files
        .filter((fn) => path.extname(fn) === `.${fileExt}`)
        .map((fn) => path.basename(fn, path.extname(fn)));
}

/**
 * 获取单个 Markdown 文件的内容
 * @param {*} dir
 * @param {*} id
 * @returns
 */
export async function getFileData(dir = "./", id) {
    const file = path.join(absPath(dir), `${id}.${fileExt}`),
        stat = await fsp.stat(file),
        data = await fsp.readFile(file, "utf8"),
        matter = fm(data),
        html = (await remark().use(remarkhtml).process(matter.body)).toString();

    // 日期格式化
    const date = matter.attributes.date || stat.ctime;
    matter.attributes.date = date.toUTCString();
    matter.attributes.dateYMD = dateformat.ymd(date);
    matter.attributes.dateFriendly = dateformat.friendly(date);

    // 计数
    const roundTo = 10,
        readPerMin = 200,
        numFormat = new Intl.NumberFormat("en"),
        count = matter.body
            .replace(/\W/g, " ")
            .replace(/\s+/g, " ")
            .split(" ").length,
        words = Math.ceil(count / roundTo) * roundTo,
        mins = Math.ceil(count / readPerMin);

    matter.attributes.wordcount = `${numFormat.format(
        words
    )} words, ${numFormat.format(mins)}-minute read`;

    return {
        id,
        html,
        ...matter.attributes,
    };
}

以上代码涉及日期格式化代码,文件路径 libs/dateformat.js

      // 时间格式化
const toMonth = new Intl.DateTimeFormat("en", { month: "long" });

// 格式化为 YYYY-MM-DD
export function ymd(date) {
    return date instanceof Date
        ? `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(
              2,
              "0"
          )}-${String(date.getUTCDate()).padStart(2, "0")}`
        : "";
}

// 格式化为 DD MMMM, YYYY
export function friendly(date) {
    return date instanceof Date
        ? `${date.getUTCDate()} ${toMonth.format(
              date
          )}, ${date.getUTCFullYear()}`
        : "";
}

Next.js 使用包含在 [id ]中的标识符的文件名来识别动态(生成)路由。创建一个名为 pages/articles/[id].js的文件: Next.js将使用 id作为参数在 /articles/article-01等路由处生成页面,即博客的详情页路由。

pages/articles/[id].js中定义函数 getStaticPaths,该函数返回构建时要呈现的路径信息。

      /**
 * 获取博客路径信息
 * @returns [ { params: { id: 'article-01' } } ]
 */
export async function getStaticPaths() {
    const paths = (await getFileIds(postsDir)).map((id) => {
        return { params: { id } };
    });
    console.log(paths);
    return {
        paths,
        fallback: false,
    };
}

设置 fallback: false会在找不到路径时出现 404 页面。

接下来创建函数 getStaticProps,函数在构建时获取特定 ID 的数据以进行静态生成。它在 params对象中传递了一个 id属性,调用 libs/posts-md.js中的 getFileData()函数解析 Markdown 文件。

      /**
 * 解析路由获取详细内容
 * @param {*} param0
 * @returns
 */
export async function getStaticProps({ params }) {
    return {
        props: {
            postData: await getFileData(postsDir, params.id),
        },
    };
}

pages/articles/[id].js除了解析博客内容外,还需将内容导出为一个 React 组件,组件将 postData渲染到前面创建的模板中:

      export default function Article({ postData }) {
    // 解析markdown内容
    const html = `
    ${postData.title}
    <p class="time"><time datetime="${postData.dateYMD}">${postData.dateFriendly}</time></p>
    <p class="words">${postData.wordcount}</p>
    ${postData.html}
  `;

    return (
        <Layout title="share.png">
            <Head>
                <title>{postData.title}</title>
                <meta name="description" content={postData.description} />
            </Head>

            <article dangerouslySetInnerHTML={{ __html: html }} />
        </Layout>
    );
}

dangerouslySetInnerHTML属性确保 HTML 不被编码。

创建博客列表页

创建文件 pages/articles/index.js,这个页面需要实现的功能是解析博客列表,并返回为一个 React 组件。在实现这个页面功能之前,先来创建一个链接组件 Pagelink

Pagelink组件实现博客列表中单篇博客的布局,创建文件 components/pagelink.js,代码如下:

      import Link from "next/link";

export default function Pagelink(props) {
    const link = `/${props.postsdir}/${props.id}`;

    return (
        <article>
            <h2>
                <Link href={link}>
                    <a>{props.title}</a>
                </Link>
            </h2>
            <p className="time">
                发布时间:
                <time dateTime={props.datefriendly}>{props.dateymd}</time>
            </p>
            <p>{props.description}</p>
        </article>
    );
}

完成单个博客布局后,来看看博客列表页,代码如下:

      import { getAllFiles } from "../../libs/posts-md";
import Layout from "../../components/layout";
import Pagelink from "../../components/pagelink";
import Head from "next/head";

const postsDir = "articles";

export default function ArticleIndex({ postData }) {
    return (
        <Layout title="share.png">
            <Head>
                <title>博客列表</title>
                <meta
                    name="description"
                    content="A list of articles published on this site."
                />
            </Head>

            博客列表

            <aside className="pagelist">
                {postData.map((post) => (
                    <Pagelink
                        key={post.id}
                        postsdir={postsDir}
                        id={post.id}
                        title={post.title}
                        description={post.description}
                        dateymd={post.dateYMD}
                        datefriendly={post.dateFriendly}
                    />
                ))}
            </aside>
        </Layout>
    );
}

/**
 * 获取所有文章文章的数组
 * @returns
 */
export async function getStaticProps() {
    return {
        props: {
            postData: await getAllFiles(postsDir),
        },
    };
}
创建导航

一个完整的博客站点,需要一个导航菜单,方便内容切换。接下来创建一个导航组件,创建文件 components/navs.js,导出一个 &lt;Navs&gt;组件,代码如下:

      import { useRouter } from "next/router";
import Link from "next/link";

// menu name and link
const menu = [
    { text: "网站首页", link: "/" },
    { text: "关于我们", link: "/about" },
    { text: "博客列表", link: "/articles" },
];

export default function Navs() {
    const router = useRouter(),
        currentPage = router.pathname;

    return (
        <nav>
            <ul>
                {menu.map((item) => (
                    <NavItem
                        key={item.link}
                        text={item.text}
                        link={item.link}
                        currentpage={currentPage}
                    />
                ))}
            </ul>
        </nav>
    );
}

function NavItem({ text, link, currentpage }) {
    if (link === currentpage) {
        return (
            <li className="active">
                <strong>{text}</strong>
            </li>
        );
    } else {
        return (
            <li>
                <Link href={link}>
                    <a>{text}</a>
                </Link>
            </li>
        );
    }
}

下面将 Navs组件加入到组件 Header 中,代码如下:

      import Link from "next/link";
import Navs from "./navs";  // 导航菜单

export default function Header({ title }) {
    const headerImg = "/images/" + (title || "cover.png");

    return (
        <header>
            <p className="logo">
                <Link href="/">
                    <a>
                        <svg
                            xmlns="http://www.w3.org/2000/svg"
                            viewBox="0 0 20 20"
                            width="50"
                            height="50"
                        >
                            <path d="M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4-1.714a1 1 0 11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7-3a1 1 0 000-1.838l-7-3zM3.31 9.397L5 10.12v4.102a8.969 8.969 0 00-1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25-3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-3.957l1.818.78a3 3 0 002.364 0l5.508-2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00-5.35 2.524 1 1 0 01-1.4 0zM6 18a1 1 0 001-1v-2.065a8.935 8.935 0 00-2-.712V17a1 1 0 001 1z"></path>
                        </svg>
                        Next.js 博客
                    </a>
                </Link>
            </p>
            <Navs />
            <figure>
                <img src={headerImg} width="400" alt="decoration" />
            </figure>
        </header>
    );
}

到此一个简单的博客站点功能已经实现。

添加样式

Next.js 提供了一系列样式选项,包括 Sass、Less、PostCSS、Styled JSX、CSS 模块和普通的CSS。 Sass 易于使用,因为不需要任何配置,按照依赖:

      npm install sass --save

根目录下创建文件夹 styles,所有的样式文件都放在这个文件夹下。样式的入口未见为 master.scss

然后在文件夹 pages下创建文件 _app.js,将样式文件导入,完整代码如下:

      import "../styles/master.scss";

export default function App({ Component, pageProps }) {
    return <Component {...pageProps} />;
}

最终效果如下:

1642841802979.jpg

1642843191606222.jpg

1642843232898333.jpg

相关 [react next js] 推荐:

乔布斯在NeXT

- xing - cnBeta.COM
导读:原文作者Tim Bray是一位加拿大的软件开发人员和企业家,他是 Open Text 和 Antarctica Systems 两家公司的联合创始人,曾在Sun公司的Web技术主管,现是Google的开发人员倡导者,专注Android. 本文由敏捷翻译 - 唐小娟编译.

谈谈 React Native

- - 唐巧的技术博客
几天前,Facebook 在 React.js Conf 2015 大会上推出了 React Native( 视频链接). 我发了一条微博( 地址),结果引来了 100 多次转发. 为什么 React Native 会引来如此多的关注呢. 我在这里谈谈我对 React Native 的理解. 一个新框架的出现总是为了解决现有的一些问题,那么对于现在的移动开发者来说,到底有哪些问题 React Native 能涉及呢.

Jquery中next和children的区别

- - CSDN博客推荐文章
next找的是同级的节点,children找的是子节点.            
  • 这是一级菜单1.                    
  • 这是二级菜单11
  • .

    Webpack 和 React 小书

    - - SegmentFault 最新的文章
    Webpack 和 React 小书. 这本小书的目的是引导你进入 React 和 Webpack 的世界. 他们两个都是非常有用的技术,如果同时使用他们,前端开发会更加有趣. 这本小书会提供所有相关的技能. 如果你只是对 React 感兴趣,那可以跳过 Webpack 相关的内容,反之亦然. 如果想学习更多的相关知识可以移步 SurviveJS - Webpack and React.

    React入门实例学习

    - - JavaScript - Web前端 - ITeye博客
            React可以在浏览器运行,也可以在服务器运行,但是在这为了尽量保持简单,且React语法是一致的,服务器的用法和浏览器差别不大,在这只涉及浏览器. 一. HTML模板.         使用React的网页源码,结构大致如下:.         1.最后一个script标签的type属性为text/jsx.

    轻松入门React和Webpack

    - - SegmentFault 最新的文章
    小广告:更多内容可以看 我的博客和 读书笔记. 最近在学习React.js,之前都是直接用最原生的方式去写React代码,发现组织起来特别麻烦,之前听人说用Webpack组织React组件得心应手,就花了点时间学习了一下,收获颇丰. 一个组件,有自己的结构,有自己的逻辑,有自己的样式,会依赖一些资源,会依赖某些其他组件.

    React 入门实例教程

    - - 阮一峰的网络日志
    现在最热门的前端框架,毫无疑问是 React. 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.

    React Native 原理与实践

    - - 掘金 前端
    React Native 介绍. 什么是 React Native. React Native 是一个由 Facebook 于 2015 年 9 月发布的一款开源的 JavaScript 框架,它可以让开发者使用 JavaScript 和 React 来开发跨平台的移动应用. 它既保留了 React 的开发效率,又同时拥有 Native 应用的良好体验,加上 Virtual DOM 跨平台的优势,实现了真正意义上的:.

    WebView JS 交互

    - - ITeye博客
    WebView加jquery做页面会怎么样呢. // 创建WebView对象. // 把programList添加到js的全局对象window中,. // 这样就可以使用window.programList来获取数据. * 定义js回调java函数. // 绑定键盘的向上,向下按钮事件触发相应的js事件.

    React Native通信机制详解

    - - bang's blog
    React Native是facebook刚开源的框架,可以用javascript直接开发原生APP,先不说这个框架后续是否能得到大众认可,单从源码来说,这个框架源码里有非常多的设计思想和实现方式值得学习,本篇先来看看它最基础的JavaScript-ObjectC通信机制(以下简称JS/OC). 普通的JS-OC通信实际上很简单,OC向JS传信息有现成的接口,像webview提供的-stringByEvaluatingJavaScriptFromString方法可以直接在当前context上执行一段JS脚本,并且可以获取执行后的返回值,这个返回值就相当于JS向OC传递信息.