前端入坑(四)--------react(如何从API获取数据)

2023-11-09

Hey! Welcome to day 4.

Hopefully you've had time to follow along and do the exercises from the last few days. And if I've done my job right, you're starting to understand how React works -- maybe even thinking about how to use it in your next project.

But there's one glaring question, and it's one of the first things React newcomers ask:

How do you get data from an API?

A fancy front end is no good without data! So today we're going to tackle that head-on by fetching some real data from Reddit and displaying it with React.

How to Fetch Data

Before we dive in, there's one thing you need to know: React itself doesn’t have any allegiance to any particular way of fetching data. In fact, as far as React is concerned, it doesn’t even know there’s a “server” in the picture at all. React is UI-only, baby.

You've already learned what makes React tick: it's props and state. And that's pretty much it. There is no HTTP library built into React. So the way to make this work is to use React's lifecycle methods to fetch data at the appropriate time, and store the response in the component's state. You can complicate this process with services and data models (er, “build abstractions”) as much as you desire, but ultimately it all boils down to components rendering props and state.

To fetch data from the server, we'll need an HTTP library. There are a ton of them out there. Fetch, Axios, and Superagent are probably the 3 most popular -- and Fetch is actually part of the JS standard library now. My favorite is Axios because of how simple it is, so that's what we'll use today. If you already know and prefer another one, go ahead and use that instead.

Create the Project

Once again we're going to start with a fresh project in CodeSandbox.

1. Go to https://codesandbox.io/s/new
2. Erase everything in index.js
3. Replace it with this:

import React from "react";
import ReactDOM from "react-dom";

class Reddit extends React.Component {
  state = {
    posts: []
  }
  render() {
    return (
      <div>
        <h1>/r/reactjs</h1>
      </div>
    );
  }
}

ReactDOM.render(<Reddit />, document.getElementById("root"));

We're creating a class component called `Reddit` to display posts from the /r/reactjs subreddit. It's not fetching anything yet, though.

By now the code probably looks familiar -- the imports at the top and the render at the bottom are the same as we've written the last few days. We're using a class component because it needs to have state to hold the posts that we fetch from the server (and function components can't hold state, remember). We're also initializing the state with an empty array of `posts`, which will soon be replaced by live data.

Render the List

Next, let's add some code to render the posts we have so far (which is an empty array). Change the `render` function to look like this:

render() {
  return (
    <div>
      <h1>/r/reactjs</h1>
      <ul>
        {this.state.posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

Let's talk about what this is doing, because it probably looks a bit weird.

Inside the <ul> the JS expression is wrapped in single braces (because, remember, that's what you gotta do in JSX). `this.state.posts` is the empty array of posts we initialized above, and the `map` function loops over the posts and returns an <li> for each item in the array.

This is how you render a list in React.

Other libraries have a special template syntax, like Angular's "ngFor" or Vue's "v-for", that essentially make a copy of the element for each item in the array.

React, on the other hand, leans on JavaScript to do the heavy lifting. "this.state.posts.map" is not a React thing. That's calling the `map` function that already exists on JS arrays, and it transforms (a.k.a, "maps") each item in the array into a new thing. In this case, each array item is being turned into a JSX <li> element with a `key` prop and the post's title, and the resulting array of <li>'s is what gets rendered inside the <ul>.

Fetch the Data

Let's see it in action with real data. First we'll import Axios, so add this new import at the top:

import axios from 'axios';

Because we haven't installed the library yet, CodeSandbox will throw up an error saying "Could not find dependency: 'axios'" but it also provides a nice "Suggested solution" in the form of a button that says "Add axios as a dependency." Click that button, and the library will be added to the project, and the app will refresh.

Then, above the render() method, type in this code:

componentDidMount() {
  axios.get(`https://www.reddit.com/r/reactjs.json`)
    .then(res => {
      const posts = res.data.data.children.map(obj => obj.data);
      this.setState({ posts });
    });
}

We're using `axios.get` to fetch the data from Reddit's API, which returns a promise, and the `.then` handler will get called once the API call is finished.

Reddit's API returns the posts in a pretty deeply-nested structure, so the `res.data.data.children.map...` is picking out the individual posts from the nested mess.

Finally, it updates the posts in the component state (remember that `this.setState({ posts })` is just ES6 shorthand for `this.setState({ posts: posts })`)

If you want to learn how to reverse-engineer API responses yourself, go to https://www.reddit.com/r/reactjs.json and copy the result into a pretty-printer like http://jsonprettyprint.com/, then look for something you recognize like a "title", and trace back upwards to figure out the JSON path to it. In this case, I looked for the "title", and then discovered posts were at res.data.data.children[1..n].data.

Once that change is made, you'll see the app re-render with real data from /r/reactjs!

If you had trouble getting it working, the full working example is here: https://codesandbox.io/s/84x08lwl09 (but hey! don't just skip the work and click the working code example -- the knowledge really sticks better when you write it out yourself).

Your Turn

Take a few seconds and run through the quick exercises below. It'll help the concepts stick! ?

  • Did you notice that the first thing we did was initialize the state with an empty array of posts? Before we even fetched the data? Try taking out the initialization and watch what happens. Burn the resulting error message into your memory: when you see this again, remember to check if you've initialized state properly, and check for typos.
  • Extend the UI to include more data from the Reddit posts, like their score and the submitting user. Make the title into a link to the actual post.

Tomorrow, we'll finally be free of the sandbox, and we'll finish up by deploying the app to the real live internet.

Cheers,
Dave

P.S. The fastest way to wrap your head around the "React way" of doing things (like rendering lists) is to practice.

It's the best method I know. But you need focused exercises.

My Pure React book comes with 26 exercises to hammer home everything you learn. Y'Eli said "I think your book is amazing. I'm really learning how to use react! I almost gave up several times using other books!"

To make sure you keep getting these emails, please add dave@daveceddia.com to your address book or whitelist us. Want out of the loop? Unsubscribe.

My postal address: P.O. Box 248, Nutting Lake, MA

我的代码实例 :)

import React from "react";
import ReactDOM from "react-dom";
import axios from 'axios';
class Reddit extends React.Component {
  state = {
    posts: []
  };
  componentDidMount(){
    axios.get(`https://www.reddit.com/r/reactjs.json`)
    .then(res =>{
      const posts = res.data.data.children.map(obj => obj.data);
      this.setState({posts})
    })
  }
  render() {
    return (
      <div>
        <h1>/r/reactjs</h1>
        <ul>
          {this.state.posts.map(post =>(
            <li key = {post.id}>{post.title}</li>
          ))}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<Reddit />, document.getElementById("root"));

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端入坑(四)--------react(如何从API获取数据) 的相关文章

  • 函数式组件与类组件有何不同?

    与React类组件相比 React函数式组件究竟有何不同 在过去一段时间里 典型的回答是类组件提供了更多的特性 比如state 当有了Hooks后 答案就不再是这样了 或许你曾听过它们中的某一个在性能上的表现优于另一个 那是哪一个 很多此类
  • React重点知识拓展,含Hooks、路由懒加载等

    第7章 React扩展 一 setState 1 setState更新状态的2种写法 setState stateChange callback 对象式的setState stateChange为状态改变的对象 该对象可以体现出状态的更改
  • React仿写网易云音乐项目

    文章目录 一 项目功能说明 二 最终效果 三 文件目录结构说明 四 项目技术栈 五 核心技术 1 配置项目别名 craco craco 2 使用reset css进行 css 重置 3 使用CSS Sprites 精灵图 4 使用 memo
  • 【前端】react-markdown配置解析

    文章目录 react markdown基本配置 同步预览配置 MdEditorComponent js reducer js initBlogState js action types js sync actions js store js
  • 【React】路由(详解)

    目录 单页应用程序 SPA 路由 前端路由 后端路由 路由的基本使用 使用步骤 常用组件说明 BrowserRouter和HashRouter的区别 路由的执行过程 默认路由 精确匹配 Switch的使用 重定向路由 嵌套路由 向路由组件传
  • 在校学生如何白嫖黑群辉虚拟机和内网穿透,实现海量资源的公网访问?(小白专用)

    文章目录 前言 本教程解决的问题是 按照本教程方法操作后 达到的效果是 前排提醒 1 搭建群辉虚拟机 1 1 下载黑群辉文件 vmvare虚拟机安装包 1 2 安装VMware虚拟机 1 3 解压黑 群辉虚拟机文件 1 4 虚拟机初始化 1
  • 配置使用Eslint的时候 版本错误 "eslint": "5.6.0" a different version of eslint was detected higher up in the tr

    1 如果你也遇到下面的问题 你可以 按照命令行提示的那样 下面这四步完成的一般就可以了 但是不排除你在运行的时候忘记下载某些依赖 1 删除 package lock json 不是package json 你可以选择 yarn lock 或
  • 【Ant Design】Form.Item创建自定义表单

    一 概述 Antd是一个非常强大的UI组件库 里面的Form表单组件也基本能满足我们大多数场景 但是也有需要自定义表单的场景 Vue2里我们使用v model 结合子组件的model属性 来实现自定义组件的双向绑定 Vue3里我们使用v m
  • Vite搭建react+ts项目

    创建一个react项目 首先需要打开终端 进行vite的引入 yarn create vite 使用react模板创建项目 yarn create vite react test template react cd react test y
  • react组件状态同步-状态提升

    假设定义组件TemperatureInputSon import React from react class TemperatureInputSon extends React Component constructor props su
  • 关于Vue.js和React.js,听听国外的开发者怎么说?

    VueJS 与 ReactJS 到底怎么样如何 听听别人怎么说 使用所有新的库和框架 很难跟上所有这些库和框架 也就是说 这就需要您决定哪些是值得花时间的 让我们看看人们说什么 和Vue JS一起工作是很愉快的 我发现学习曲线很浅 然而 这
  • React中使用if else 条件判断

    在react中用jsx渲染dom的时候经常会遇到if条件判断 然而在jsx中竟是不允许if条件判断的 以下有几种判断方式 可以根据自己的应用场景 挑选适合的 方案一 class HelloMessage extends React Comp
  • React解密:React Hooks函数之useCallback和useMemo

    之所以将useCallback和useMemo放到一起 从某种意义上说 他们都是性能优化的始作俑者 他们也有很多的共性 我们先来回顾一下class组件性能优化的点 调用 setState 就会触发组件的重新渲染 无论前后 state 是否相
  • umi 后台管理demo

    umi 后台管理demo umi react ts dva antd egg 有待优化 简单的前后端管理demo 接口提供增删查改 前端也有相应功能 github代码 https github com huiBuiling ql admin
  • React、Vue2.x、Vue3.0的diff算法

    前言 本文章不讲解 vDom 实现 mount 挂载 以及 render 函数 只讨论三种 diff 算法 VNode 类型不考虑 component functional component Fragment Teleport 只考虑 E
  • quill编辑器使用

    官方git https github com quilljs quill 官方文档 https quilljs com 中文文档 https kang bing kui gitbook io quill 编辑器是个正经编辑器 就是文档太不正
  • 值得收藏的UmiJS 教程

    点击上方关注 前端技术江湖 一起学习 天天进步 前言 网上的umi教程是真的少 很多人都只写了一点点 很多水文 所以打算自己写一篇 自己搭建umi 并封装了一下常用的功能 并用到公司实际项目中 umi介绍 Umi 是什么 Umi 中文可发音
  • 如何替换对象的key值

    发生的场景 现在用antd组件库 有些组件想渲染数据的话 我要根据他们官网给的字段名称对应起来才能渲染上去 这个是复选框选中 保存的时候 字段需要按照后台约定的传入code value 1 常规循环遍历 大招来了 哈哈哈 才疏学浅 我觉得是
  • error Missing “key“ prop for element in array react/jsx-key

    react遇到一个奇怪的问题 error Missing key prop for element in array react jsx key 检查了jsx中使用map的 都定义了key div otherList map item an
  • React中渲染html结构---dangerouslySetInnerHTML

    dangerouslySetInnerHTML 胡子 语法绑定的内容全部作为普通文本渲染 渲染html结构基于 dangerouslySetInnerHTML dangerouslySetInnerHTML 是 React 标签的一个属性

随机推荐