美文网首页
useReducer结合useContext

useReducer结合useContext

作者: 西域战神 | 来源:发表于2020-07-03 08:02 被阅读0次

    1.初始化

    首先创建Users,Books,Movies以及App组件

    import React from "react";
    import ReactDOM from "react-dom";
    
    function App() {
      return (
        <div>
          <User />
          <hr />
          <Books />
          <Movies />
        </div>
      );
    }
    
    function User() {
      return (
        <div>
          <h1>个人信息</h1>
          <div>name:</div>
        </div>
      );
    }
    
    function Books() {
      return (
        <div>
          <h1>我的书籍</h1>
          <ol>
            <li>Effective Java</li>
            <li>Introduction Java</li>
          </ol>
        </div>
      );
    }
    
    function Movies() {
      return (
        <div>
          <h1>我的电影</h1>
          <ol>
            <li>蝙蝠侠</li>
            <li>复仇者联盟</li>
          </ol>
        </div>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    
    image.png

    创建一个默认store,reducer以及context

    const Context = React.createContext(null);
    const store = {
      user: null,
      books: null,
      movies: null
    };
    const reducer = (state, action) => {
      switch (action.type) {
        case "setUsers":
          return { ...state, users: action.users };
        case "setMovies":
          return { ...state, movies: action.movies };
        case "setBooks":
          return { ...state, books: action.books };
        default:
          throw new Error();
      }
    };
    

    使用useReducer创建读写api,然后将其放入context中

    function App() {
      const [state,dispatch] = useReducer(reducer,store)
      return (
        <Context.Provider value={{state,dispatch}}>
          <User />
          <hr />
          <Books />
          <Movies />
        </Context.Provider>
      );
    }
    

    写一个mock的fetch函数

    function fetch(path) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (path === "/user") {
            resolve({
              id: 1,
              name: "Larry"
            });
          } else if (path === "/books") {
            resolve([
              {
                id: 1,
                name: "Effective Java"
              },
              {
                id: 2,
                name: "Introduction Java"
              }
            ]);
          } else if (path === "/movies") {
            resolve([
              {
                id: 1,
                name: "复仇者联盟"
              },
              {
                id: 2,
                name: "蝙蝠侠"
              }
            ]);
          }
        }, 2000);
      });
    }
    

    在User组件中调用fetch,并且触发dispatch

    function User() {
      const { state, dispatch } = useContext(Context);
      useEffect(()=>{
        fetch("/user").then(users => {
          dispatch({ type: "setUsers", users });
        });
      },[])
    
      return (
        <div>
          <h1>个人信息</h1>
          <div>name:{state.user ? state.user.name : ""}</div>
        </div>
      );
    }
    

    这时我们成功触发了'setUsers'的dispatch,可以正确显示结果.
    同理,我们可以'setbooks'和'setMovies'

    
    function Books() {
      const { state, dispatch } = useContext(Context);
      useEffect(() => {
        fetch("/books").then(books => {
          console.log(books);
          dispatch({ type: "setBooks", books: books });
        });
      }, []);
      return (
        <div>
          <h1>我的书籍</h1>
          <ol>
            {state.books
              ? state.books.map(book => <li key={book.id}>{book.name}</li>)
              : "加载中"}
          </ol>
        </div>
      );
    }
    
    function Movies() {
      const { state, dispatch } = useContext(Context);
      useEffect(() => {
        fetch("/movies").then(movies => {
          dispatch({ type: "setMovies", movies: movies });
        });
      }, []);
      return (
        <div>
          <h1>我的电影</h1>
          <ol>
            {state.movies
              ? state.movies.map(movie => <li key={movie.id}>{movie.name}</li>)
              : "加载中"}
          </ol>
        </div>
      );
    }
    
    image.png

    相关文章

      网友评论

          本文标题:useReducer结合useContext

          本文链接:https://www.haomeiwen.com/subject/njsjqktx.html