用一个简单的获取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> |
| ) |
| } |