2022 React 最速上手指南(十三)—— 内联处理函数 & 异步数据

这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战

以结果为导向,写给刚学完前端三剑客和想要了解 React 框架的小伙伴,使得他们能快速上手(省略了历史以及一些不必要的介绍)。

JSX 内联处理函数

到目前为止,我们拥有的 stories 列表只是一个无状态的变量,可以通过搜索来过滤渲染的列表,但是列表本身保持不变。

如果我们想要加一个【从列表中删除项目】的功能,就要取得列表的控制权,我们可以把列表作为 useState hook 的初始 state(之所以不使用我们自定义的 hook,是因为我们不想每次打开浏览器显示的都是缓存列表),然后向下传递一个回调处理函数。

const initialStories = [
  ...
];

...

const App = () => {
  ...
  
  const [stories, setStories] = React.useState(initialStories);

  const handleRemoveStory = (item) => {
    const newStories = stories.filter(
      (story) => item.objectID !== story.objectID
    );
    setStories(newStories);
  };

  ...

  return (
    <>
      <InputWithLabel
        id="search"
        value={searchTerm}
        onInputChange={handleSearch}
        isFocused
      >
        <strong>Search:</strong>
      </InputWithLabel>

      <hr />
      <List list={searchedStories} onRemoveItem={handleRemoveStory} />
    </>
  );
};
复制代码

回调函数接收要删除的 item,然后将返回的 newStories 设置为新的 state。

List 组件会向下传递这个函数给它的子组件:

const List = ({ list, onRemoveItem }) =>
  list.map((item) => (
    <Item key={item.objectID} item={item} onRemoveItem={onRemoveItem} />
  ));

const Item = ({ item, onRemoveItem }) => (
  <div>
    <span>
      <a href={item.url}>{item.title}</a>
    </span>
    <span>{item.author}</span>
    <span>
      <button onClick={() => onRemoveItem(item)}>Dismiss</button>
    </span>
  </div>
);
复制代码

使用【内联处理函数】,在点击按钮时调用 App 组件里的 onRemoveItem() 触发删除事件。

它与常规的处理函数类似,只是函数体放在了 JSX 中,但由于 JS 逻辑隐藏在 JSX 中,可能会导致代码难以调试,所以在【实现逻辑冗长】时,我们应该避免使用内联处理函数,而是直接采用常规方式,就像这样:

const Item = ({ item, onRemoveItem }) => {
  const handleRemoveItem = () => {
    onRemoveItem(item);
  };
 
  return (
    <div>
      <span>
        <a href={item.url}>{item.title}</a>
      </span>
      <span>{item.author}</span>
      <span>
        <button onClick={handleRemoveItem}>Dismiss</button>
      </span>
    </div>
  );
};
复制代码

异步数据

在真实应用中,我们一般先要渲染出一个组件,然后再请求第三方 API 得到数据并将其显示在组件上。

我们使用一个空数组作为初始的 state,然后通过一个简单的 promise 函数加上一点延迟来【模拟异步获取数据的过程】:

const getAsyncStories = () =>
  new Promise((resolve) =>
    setTimeout(() => resolve({ data: { stories: initialStories } }), 2000)
  );

const App = () => {
  ...
  
  const [stories, setStories] = React.useState([]);

  React.useEffect(() => {
    getAsyncStories().then((res) => {
      setStories(res.data.stories);
    });
  }, []);

  ...
};
复制代码

由于 useEffect 的依赖数组是【空数组】,因此副作用函数仅在组件首次渲染后执行,函数在解析完 promise 并修改 state 后,组件会再次渲染并显示异步加载的数据。

关于 promise 的用法这里写一个示例,查看文档阅读更多。

const makeServerRequest = new Promise((resolve, reject) => {
  // 做一些异步操作,假设从远端API调取数据
  
  // 成功拿到数据调用resolve(),失败调用reject()
  if(responseFromServer) {
    resolve("We got the data");
  } else {  
    reject("Data not received");
  }
});

// resolve()执行时调用
makeServerRequest.then(result => {
  console.log(result); // "We got the data"
});

// reject()执行时调用
makeServerRequest.catch(error => {
  console.log(error); // "Data not received"
});
复制代码

专栏

因为参加打卡活动是每日更新,所以可能比较短小,可以关注一下 React 入门专栏

在更新完后会整合为一整篇,感谢关注和点赞!

Guess you like

Origin juejin.im/post/7068603473331224612