使用带axios的Reducer来提取数据



很抱歉,如果这是一个愚蠢的问题,我还不太了解React。

以下是我正在使用的内容:

import React, { useReducer } from "react";
import axios from "axios";
export const ACTIONS = {
ADD_STANDARD: 'add-to-compare',
REMOVE_STANDARD: 'remove-from-compare'
}
function reducer(standards, action) {
switch(action.type) {
case(ACTIONS.ADD_STANDARD):
return [...standards, addCompare(action.payload.standard)]
case(ACTIONS.REMOVE_STANDARD):
return standards.filter(item => item.id !== action.payload.standard)
default:
return 'Nothing to add'
}
}
function addCompare( standard ) {
return axios
.get("https://the-url.com" + standard)
.then((res) => {
console.log(res.data)
return {
key: res.data.id,
title: res.data.title.rendered
}
})
.catch((err) => console.log(err));
}
export default function EntryStandards() {
const [standards, dispatch] = useReducer(reducer, []);
const addStandards = function(id) {
dispatch({ type: ACTIONS.ADD_STANDARD, payload: {standard: id}})
}
return (
<>
<button onClick={() => addStandards(9603)}>Add 9603!</button>
<button onClick={() => addStandards(9567)}>Add 9567!</button>
<button onClick={() => addStandards(9531)}>Add 9531!</button>
<button onClick={() => addStandards(9519)}>Add 9519!</button>
{standards.map(standard => {
return <p><button onClick={() => dispatch({ type: ACTIONS.REMOVE_STANDARD, payload: { standard: standard.id } })}>X</button> { standard.title } - { standard.version }</p>
})}
</>
)
}

正如你所看到的,我现在有一个按钮,它有一个硬编码的ID。当点击时,该按钮会触发useReducer上的调度,该调度使用Axios针对WordPress的Rest API执行API数据查找。

如果我在Axios返回中控制台日志,我会看到数据。但是,直接在我创建对象的地方返回只是将一个空对象返回到reducer中。

调度员不能以这种方式使用Axios吗?

有更好的方法吗?

一如既往,我们非常感谢您的帮助。

Ben

addCompare是一个异步函数。因此,您不能在reducer中直接使用它,因为reducer必须同步返回结果。

您可能需要更改代码以启动您的请求,然后使用reducer添加如下数据:

import React, { useReducer } from "react";
import axios from "axios";
export const ACTIONS = {
ADD_STANDARD: 'add-to-compare',
REMOVE_STANDARD: 'remove-from-compare'
}
function reducer(standards, action) {
switch(action.type) {
case(ACTIONS.ADD_STANDARD):
return [...standards,action.payload.standard]
case(ACTIONS.REMOVE_STANDARD):
return standards.filter(item => item.id !== action.payload.standard)
default:
return 'Nothing to add'
}
}
function addCompare( standard ) {
return axios
.get("https://the-url.com" + standard)
.then((res) => {
console.log(res.data)
return {
key: res.data.id,
title: res.data.title.rendered
}
})
.catch((err) => console.log(err));
}
export default function EntryStandards() {
const [standards, dispatch] = useReducer(reducer, []);
const addStandards = async function(id) {
const standard = await addCompare(id)
dispatch({ type: ACTIONS.ADD_STANDARD, payload: { standard }})
}
return (
<>
<button onClick={() => addStandards(9603)}>Add 9603!</button>
<button onClick={() => addStandards(9567)}>Add 9567!</button>
<button onClick={() => addStandards(9531)}>Add 9531!</button>
<button onClick={() => addStandards(9519)}>Add 9519!</button>
{standards.map(standard => {
return <p><button onClick={() => dispatch({ type: ACTIONS.REMOVE_STANDARD, payload: { standard: standard.id } })}>X</button> { standard.title } - { standard.version }</p>
})}
</>
)
}

感谢Gabriel对异步的见解。这感觉不是一个整洁的解决方案,但我最终让reducer只存储帖子的ID,然后导入一个新组件,该组件获取ID并执行Axios阶段的数据映射。谢谢你在这方面的帮助。

最新更新