API调用时如何在reducer函数中返回状态



我有一个reducer函数,我必须在其中进行API调用,然后将其结果作为状态返回。但是由于API调用是异步的,所以state的值不会更新。

if (action.type==='CREATE_POST') {
const x= async () => {
const res=await  fetch("http://localhost:5000/posts", {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(
action.payload
)
})
const data= await res.json()
return data
}
return [...state,x]
}

我也试过这个

if (action.type==='CREATE_POST') {
const x= async () => {
const res=await  fetch("http://localhost:5000/posts", {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(
action.payload
)
})
const data= await res.json()
return data
}
return [...state,x().then((data)=>{console.log(data);})]
}

如果您正在执行异步任务,我建议您使用以下模式:

创建三个文件,命名为:

  1. reducer.js
  2. action.js
  3. effect.js(异步任务)
  4. 在减速机

const initialState = {
loading: false,
data: [],
error: ''
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case "FETCH_REQUEST":
return {
...state,
loading: true
}
case "FETCH_SUCCESS":
return {
loading: false,
data: action.payload,
error: ''
}
case "FETCH_FAILURE":
return {
loading: false,
data: [],
error: action.payload
}
default: return state
}
}
export default reducer

在action.js

export const fetchRequest = () => {
return {
type: "FETCH_REQUEST"
}
}

export const fetchSuccess = data => {
return {
type: "FETCH_SUCCESS",
payload: data
}
}

export const fetchFailure = error => {
return {
type: "FETCH_FAILURE",
payload: error
}
}

最后effect.js

export const fetch = () => {
return (dispatch) => {
//Initializing the request
dispatch(fetchRequest());
//Calling the api
api()
.then((response) => {
// response is the data
dispatch(fetchSuccess(response));
})
.catch((error) => {
// error.message is the error message
dispatch(fetchFailure(error.message));
});
};
};

不要从reducer调用API, reducer是纯函数,它不会等待API调用完成和更新状态。

最好的方法是创建另一个与组件分离的函数/钩子,并在那里执行所有这些操作,这样你的组件就会很干净。

我使用下面的方法来解决这个问题,我为每个服务创建一个自定义钩子,如useuserdisach, useAuthDispatch等,以使所有这些逻辑远离组件。

你可以根据你的用例为每个页面/模块/服务等创建一个自定义调度程序。

自定义钩

const usePostDispatch = () => {
const dispatch = useDispatch();
const getPosts = async () => {
try {
dispatch({ type: "FETCH_REQUEST" });
const res = await fetch("http://localhost:5000/posts", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(action.payload),
});
const data = await res.json();
dispatch({ type: "FETCH_SUCCESS", payload: data });
return data;
} catch (error) {
dispatch({ type: "FETCH_FAILURE", payload: error });
}
};
return {
getPosts,
};
};

减速器

const initialState = {
loading: false,
data: [],
error: "",
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "FETCH_REQUEST":
return {
...state,
loading: true,
};
case "FETCH_SUCCESS":
return {
loading: false,
data: action.payload,
error: "",
};
case "FETCH_FAILURE":
return {
loading: false,
data: [],
error: action.payload,
};
default:
return state;
}
};
export default reducer;
<<p>组件/strong>
const { getPosts } = usePostDispatch(); // Make sure you call this at top level
useEffect(() => {
getPosts();
}, []);

最新更新