具体操作
- 将数据集中在一个store对象
const store = {
user: null,
books: null,
movies: null
};
- 将所有操作集中在reducer上
function reducer(state, action) {
if (action.type === "setUser") {
return { ...state, user: action.user };
} else if (action.type === "setBooks") {
return { ...state, books: action.books };
} else if (action.type === "setMovies") {
return { ...state, movies: action.movies };
} else {
throw new Error();
}
}
- 创建一个Context
const Context = React.createContext(null);
- 创建对数据读写的API
const [state, dispatch] = useReducer(reducer, store);
- 将读写的的API放到Context中
function App() {
const [state, dispatch] = useReducer(reducer, store);
const api = { state, dispatch };
return (
<Context.Provider value={api}>
</Context.Provider>
);
}
- 用Context.Provider将Context提供给所有的组件
function App() {
const [state, dispatch] = useReducer(reducer, store);
const api = { state, dispatch };
return (
<Context.Provider value={api}>
<User />
<hr />
<Books />
<Movies />
</Context.Provider>
);
}
- 在组件中可以使用useContext获得读写的API
function User() {
const { state, dispatch } = useContext(Context);
useEffect(() => {
ajax("/user").then(user => {
dispatch({ type: "setUser", user: user });
});
}, []);
return (
<div>
<h1>个人信息</h1>
<div>name: {state.user ? state.user.name : ""}</div>
</div>
);
}
组件(二)
function Books() {
const { state, dispatch } = useContext(Context);
useEffect(() => {
ajax("/books").then(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>
);
}
模拟ajax请求
function ajax(path) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (path === "/user") {
resolve({
id: 1,
name: "Frank"
});
} else if (path === "/books") {
resolve([
{
id: 1,
name: "JavaScript 高级程序设计"
},
{
id: 2,
name: "JavaScript 精粹"
}
]);
} else if (path === "/movies") {
resolve([
{
id: 1,
name: "爱在黎明破晓前"
},
{
id: 2,
name: "恋恋笔记本"
}
]);
}
}, 2000);
});
}
最后 进行模块化来提高复用。