typescript - 使用 SolidJS 中的 fetch API 渲染远程数据

标签 typescript async-await fetch-api solid-js

我是使用 Solid JS(以及就此而言的 JS)的新手,在尝试填充(自定义)<Table> 时,我面临着看似奇怪的行为。使用来自 API 的数据的组件 fetch() .

这是我的<Table> :

import { Component, For } from "solid-js";
import "jquery";
import "datatables.net-bs5";

const Table: Component<{ id: string; columns: string[]; data: any[] }> = ({
  id,
  columns,
  data,
}) => {
  return (
    <>
      <div class="table-responsive">
        <table id={id} class="table table-striped table-hovr">
          <thead>
            <For each={columns}>{(col: string) => <th>{col}</th>}</For>
          </thead>
          <tbody>
            <For each={data}>
              {(row: {}) => (
                <tr>
                  <For each={Object.values(row)}>
                    {(d: any) => <td>{d}</td>}
                  </For>
                </tr>
              )}
            </For>
          </tbody>
        </table>
      </div>

    </>
  );
};

export default Table;

这是我想要放置数据的地方:

import { Component, createSignal} from 'solid-js';
import Table from '../components/Table';
import "jquery";
import "datatables.net-bs5";
import { getRequest } from '../utils/utils';
import Customer from '../entities/Customer';



const Customers: Component = () => {
    const [customers, setCustomers] = createSignal<Customer[]>([]);

    const columns = [
        'ID Cliente',
        'Numero Cliente',
        'Azienda?', 
        'Nome',
        'Cognome',
        'Sesso',
        'Data di nascita',
        'Via',
        'Città',
        'CAP',
        'Telefono',
        'E-mail'
       ] /* Display name of the columns */

       
   const req =  getRequest("/customers").then((data) => setCustomers(data)
   ).catch((e) => window.location.href="/");

   

    return <>
            <h2>Clienti</h2>
            <br />
            <Table id="main-table" columns={columns} data={customers()}></Table>
            </>
    
}

export default Customers;

function createStore<T>(arg0: never[]): [any, any] {
    throw new Error('Function not implemented.');
}

这是我用来获取数据的函数:

export async function getRequest(endpoint : string) {
  const response = await fetch(config.api_url + endpoint, {
        method: "GET",
        "headers": {
            "Authorization": config.jwt
        }
    });
    return response.json();
}

基本上,问题是我在 <Table> 中更改某些内容后第一次看到网页上表格内的数据。并保存。当我重新加载页面(以及所有其他访问)时,我只看到 <th> s 和一个空的表体。

我认为我误解了 SolidJS Signal,但我不确定。

您能告诉我我做错了什么吗?

谢谢。 数控

我尝试使用 Solid JS Signal 但没有成功

最佳答案

您可以使用资源或直接使用获取 API。资源允许您在渲染组件之前获取数据。

使用资源

Solid 有一个专用的 API,用于获取和渲染使用 createResource 创建的远程数据:

https://www.solidjs.com/docs/latest/api#createresource

资源允许您管理查询参数并在正在进行的请求的不同阶段呈现不同的元素。

const [data, { mutate, refetch }] = createResource(getQuery, fetchData);

这里,getQuery是一个携带查询参数的信号。它是可选的,更新它会导致自动重新获取。

fetchData 是 getter 函数,它以资源的形式返回 promise 。

data 是一个具有附加属性的 getter 函数:

  • data() 返回成功值。
  • data.states 返回正在进行的 Promise 的状态。
  • data.error 返回失败的原因,以防 promise 被拒绝。 我将保持简短以避免重复文档。

这是一个工作演示:https://playground.solidjs.com/anonymous/6b063de1-584c-4691-aa38-cf8791070962

import { render } from "solid-js/web";
import { createSignal, Switch, Match, createResource } from "solid-js";

const getUsers = () => new Promise(resolve => {
  const users = [
    'Vivian Li',
    'Lina Delgado',
    'Aimee Navarro',
    'Enzo Larsen',
    'Diana Doyle',
    'Elspeth Meyers',
    'Michael Roberson',
    'Junior Sparks',
    'Daniela Orozco',
    'Esme Larson',
  ];
  setTimeout(() => resolve(users), 1000);
});

function App() {
  const [data] = createResource(getUsers);

  return (
    <div>
      <Switch fallback={<div>Not Found</div>}>
        <Match when={data.state === 'pending' || data.state === 'unresolved'}>
          Loading...
        </Match>
        <Match when={data.state === 'ready'}>
          {JSON.stringify(data())}
        </Match>
        <Match when={data.state === 'errored'}>
          {JSON.stringify(data.error)}
        </Match>
      </Switch>
    </div>
  );
}

render(App, document.getElementById("app")!);

直接使用 fetch API

您可以直接在组件中使用 fetch API,但您必须自己管理状态,以反射(reflect)正在进行的请求的状态。

为了使代码自给自足,我将使用 Promise,但您可以使用 fetch 函数,代码的工作原理相同。

在这里您可以找到演示:https://playground.solidjs.com/anonymous/a0b41605-f490-4787-bba0-130312cc2ba9

import { render } from "solid-js/web";
import { createSignal, Switch, Match } from "solid-js";

const getUsers = () => Promise.resolve([
  'Vivian Li',
  'Lina Delgado',
  'Aimee Navarro',
  'Enzo Larsen',
  'Diana Doyle',
  'Elspeth Meyers',
  'Michael Roberson',
  'Junior Sparks',
  'Daniela Orozco',
  'Esme Larson',
]);

function App() {

  interface State {
    status: 'pending' | 'resolved' | 'rejected';
    data?: any;
    error?: any;
  };

  const [state, setState] = createSignal<State>({ status: 'pending' });

  const handleClick = () => {
    getUsers()
      .then(data => setState({ status: 'resolved', data, error: undefined }))
      .catch(error => setState({ status: 'rejected', error }));
  }

  return (
    <div>
      <div>
      <button type="button" onClick={handleClick}>
        Fetch Users
      </button>
      </div>
      <Switch fallback={<div>Not Found</div>}>
        <Match when={state().status === 'pending'}>
          Loading...
        </Match>
        <Match when={state().status === 'resolved'}>
          {JSON.stringify(state().data)}
        </Match>
        <Match when={state().status === 'rejected'}>
          {JSON.stringify(state().error)}
        </Match>
      </Switch>
    </div>
  );
}

render(App, document.getElementById("app")!);

在演示中,数据是通过点击处理程序获取的,但您可以将获取逻辑移至组件主体中并自动执行获取。

function App() {
  interface State { status: 'pending' | 'resolved' | 'rejected', data?: any, error?: any };
  const [state, setState] = createSignal<State>({ status: 'pending' });
  
  getUsers()
      .then(data => setState({ status: 'resolved', data, error: undefined }))
      .catch(error => setState({ status: 'rejected', error }));

  return (
    <div>
      <div>
        <button type="button">
          Fetch Users
        </button>
      </div>
      <Switch fallback={<div>Not Found</div>}>
        <Match when={state().status === 'pending'}>
          Loading...
        </Match>
        <Match when={state().status === 'resolved'}>
          {JSON.stringify(state().data)}
        </Match>
        <Match when={state().status === 'rejected'}>
          {JSON.stringify(state().error)}
        </Match>
      </Switch>
    </div>
  );
}

关于typescript - 使用 SolidJS 中的 fetch API 渲染远程数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74589998/

相关文章:

c# - 为什么 "async void"方法会同步运行?

使用 Electron 的 CORS 请求

javascript - 如何在获取后调用后管理重定向请求

angular - 在新标签页中打开新窗口

typescript - 命名泛型函数的返回类型

typescript - 如何防止 Vetur 和 TypeScript 在 VSCode 中同时显示 TypeScript 警告?

python - 使用 contextvar 跟踪 Python 中的异步循环

swift - 如何使用新的 swift async/await 方法上传数据?

javascript - 使用 vanilla Javascript 获取数据并以 html 形式显示

javascript - 类型错误 : Cannot read property 'settDate' of undefined