如何使用 Redux 和 API 服务器为 CRUD 应用程序设置路由参数

How to set route params for CRUD application using Redux and API server

我正在开发一个 React/Redux 应用程序,它需要向 API 服务器端点 (/contents/{id}) 发出简单的 GET 请求。现在我设置了一个操作来获取这些数据:

export const fetchInfoPage = id => {
return async dispatch => {
    try {
    const res = await fetch(`${server}/contents/${id}`)
    if (res.ok) {
        const json = await res.json()
        await dispatch(fetchPageRequest())
        await setTimeout(() => {
        dispatch(fetchPageSuccess(json.data))
        }, 1000)
    } else {
        const json = await res.json()
        console.log(res, json)
    }
    } catch (error) {
    dispatch(fetchPageFailure(error))
    console.log(error)
    }
  }
}

下面是 fetchPageSuccess 的样子:

const fetchPageSuccess = content => {
    const { id, attributes } = content
    return {
        type: FETCH_PAGE_SUCCESS,
        isFetching: false,
        id: id,
        name: attributes.name,
        content: attributes.content,
        created_by: attributes.created_by,
        updated_by: attributes.updated_by,
        created_at: attributes.created_at,
        updated_at: attributes.updated_at
    }
}

我在我的 InfoPage 组件中的 componentDidMount 中使用 fetchInfoPage(match.params.name) 触发此操作。 match.params.name 设置为匹配 React Route 中的参数(即 /:name/information)。我想改为使用 JSON 中的 ID 号来获取数据,同时仍然显示 :name 作为路由参数。

我觉得我已经接近完成这项工作了,但我的逻辑某处存在差距。有可能做我想在这里做的事吗?我还可以访问 /contents/slug/{slug}.

的 GET 端点

你正在尝试做的事情完全没问题。 只需使用您的 json 中的 fetchInfoPage 中的名称映射 id,或者您实际上可以将 id 从组件发送到您的 fetchInfoPage 函数。它与您的路线参数无关。您所做的就是从您的参数中获取名称并使用您的名称获取相应的 ID。我假设你有一个 name: id map somewhere.

export const fetchInfoPage = name => {
return async dispatch => {
    try {
    const id = getIdFromName(name); // Write a helper function
    const res = await fetch(`${server}/contents/${id}`)
    if (res.ok) {
        const json = await res.json()
        await dispatch(fetchPageRequest())
        await setTimeout(() => {
        dispatch(fetchPageSuccess(json.data))
        }, 1000)
    } else {
        const json = await res.json()
        console.log(res, json)
    }
    } catch (error) {
    dispatch(fetchPageFailure(error))
    console.log(error)
    }
  }
}

你的路线仍然是/:name/information

我最后做的是 slug 获取。在我获取数据的组件上,我通过使用路由中的 match.params.namecomponentDidMount 中创建了 slug 名称,然后触发 fetchInfoPage(slugName) 以获取数据。我还对代码进行了大量清理,所以现在 fetchInfoPage 是这样的:

export const fetchInfoPage = slug => {
  return async dispatch => {
    try {
      dispatch(fetchPageRequest())
      const res = await fetch(`${server}/contents/slug/${slug}`)
      const contentType = res.headers.get('content-type')
      if (contentType && contentType.includes('application/vnd.api+json')) {
        const json = await res.json()
        if (res.ok) {
          dispatch(fetchPageSuccess(json))
        } else {
          printError(res, json)
          dispatch(fetchPageFailure(res.body))
          dispatch(push('/error'))
        }
      } else {
        console.log('Not valid JSON')
        dispatch(fetchPageFailure(res.body))
        dispatch(push('/error'))
      }
    } catch (error) {
      dispatch(fetchPageFailure(error))
      dispatch(push('/error'))
      console.log(`Network error: ${error.message}`)
    }
  }
}

还有一个componentDidMount例子:

componentDidMount() {
    const { match, fetchInfoPage } = this.props
    const slugName = `${NAMESPACE}-${match.params.name}`
    fetchInfoPage(slugName)
}