useReducer结合useContext
2020-07-03 本文已影响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);

创建一个默认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>
);
}
