useState对比useReducer

5/10/2022 #reactjs #hooks

用一个简单的获取post的例子来对比useState和useReducer

useState

const Post = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [post, setPost] = useState({});
const handleFetch = () => {
setLoading(true);
setError(false);
fetch("api/post")
.then((res) => res.json())
.then((data) => {
setLoading(false);
setPost(data);
})
.catch((err) => {
setLoading(false);
setError(true);
});
};
return (
<div>
<button onClick={handleFetch}>
{loading ? "Wait..." : "Fetch the post"}
</button>
<p>{post?.title}</p>
<span>{error && "Something went wrong!"}</span>
</div>
)
}

useReducer

区别于useState,useReducer需要一些准备工作

const ACTION_TYPES = {
FETCH_START: "FETCH_START",
FETCH_SUCCESS: "FETCH_SUCCESS",
FETCH_ERROR: "FETCH_ERROR",
};
const INITIAL_STATE = {
loading: false,
post: {},
error: false,
};
const postReducer = (state, action) => {
switch (action.type) {
case ACTION_TYPES.FETCH_START:
return {
loading: true,
error: false,
post: {},
};
case ACTION_TYPES.FETCH_SUCCESS:
return {
...state,
loading: false,
post: action.payload,
};
case ACTION_TYPES.FETCH_ERROR:
return {
error: true,
loading: false,
post: {},
};
default:
return state;
}
};
const Post = () => {
const [state, dispatch] = useReducer(postReducer, INITIAL_STATE);
const handleFetch = () => {
dispatch({ type: ACTION_TYPES.FETCH_START });
fetch("api/post")
.then((res) => {
return res.json();
})
.then((data) => {
dispatch({ type: ACTION_TYPES.FETCH_SUCCESS, payload: data });
})
.catch((err) => {
dispatch({ type: ACTION_TYPES.FETCH_ERROR });
});
};
return (
<div>
<button onClick={handleFetch}>
{state.loading ? "Wait..." : "Fetch the post"}
</button>
<p>{state.post?.title}</p>
<span>{state.error && "Something went wrong!"}</span>
</div>
)
}