在之前的开发和学习中, 对redux 一直觉得很难用, 然后又不得不用, 于是就翻博客学习,下面正式开始
使用react-cli初始化项目, 然后在src新建index.js
import ReactDOM from 'react-dom';
function App() {
return (
<div>app</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
运行项目,yarn start 可以看到 浏览器中出现app 就初始化好了
新建books, music, user 三个组件 , ,并在index 中引入三个组件 并展示
- books, music, user
function Books() {
return (
<div>
<h1>Books</h1>
</div>
)
}
export default Books;
function User() {
return (
<div>
<h1>User</h1>
</div>
)
}
export default User;
function Music() {
return (
<div>
<h1>Music</h1>
</div>
)
}
export default Music;
- 然后在app 中引入
import Books from "./books/books";
import User from "./user/user";
import Music from "./music/music";
function App() {
return (
<div>
<User />
<hr>
<Books />
<Music />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
- 看看运行结果
在src目录新建context 文件, 并在app 中引入
import {createContext} from 'react'
const AppContext = createContext(null);
export default AppContext;
在index 中引入context , 并添加initState
import ReactDOM from 'react-dom';
import Books from "./books/books";
import User from "./user/user";
import Music from "./music/music";
import AppContext from "./context/context";
const initState = {
books: null,
music: null,
user: null
}
function App() {
return (
<div>
<User />
<hr/>
<Books />
<Music />
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
在src下新建reducers目录, 添加 user_reducer.js , book_reducer.js, music_reducer.js
export default {
getBooks: (state, action) => {
return {...state,books: action.books}
}
}
export default {
getMusic: (state, action) => {
return {...state, music: action.music}
}
}
export default {
getUser: (state, action) => {
return {...state, user: action.user}
}
}
在index 文件中引入reducer, 并新建recuderConfig, 配合context, 完成 reducer 初始化
import ReactDOM from 'react-dom';
import Books from "./books/books";
import User from "./user/user";
import Music from "./music/music";
import AppContext from "./context/context";
import bookReducer from "./reducers/book_reducer";
import musicReducer from "./reducers/music_reducer";
import userReducer from "./reducers/user_reducer";
import {useReducer} from "react";
const initState = {
books: null,
music: null,
user: null
}
const reducerConfig = {
...bookReducer,
...musicReducer,
...userReducer
}
const reducer = (state, action) => {
const dispatchFn = reducerConfig[action.type];
if (dispatchFn) {
const storeState = dispatchFn(state, action);
return storeState;
} else {
throw new Error('不认识');
}
}
function App() {
const [state, dispatch] = useReducer(reducer, initState);
return (
<AppContext.Provider value={{state, dispatch}}>
<User />
<hr/>
<Books />
<Music />
</AppContext.Provider>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
在src目录新建ajax.js 模拟请求
// 假 ajax
// 两秒钟后,根据 path 返回一个对象,必定成功不会失败
function ajax(path) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (path === "/user") {
resolve({
id: 1,
name: "笑嘻嘻"
});
} 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);
});
}
export default ajax;
在user组件中使用ajax, 并渲染数据
function User() {
const {state, dispatch} = useContext(AppContext);
useEffect(()=> {
ajax('/user').then(res => dispatch({type: "getUser", user: res}))
}, [])
return (
<div>
<h1>User</h1>
<div>{state?.user ? state?.user?.name : '加载中' }</div>
</div>
)
}
export default User;
在 books 中引入, 并渲染
import AppContext from "../context/context";
import ajax from "../ajax";
import {useContext, useEffect} from "react";
function Books() {
const {state, dispatch} = useContext(AppContext);
useEffect(()=> {
ajax('/books').then( res => dispatch({type: 'getBooks', books: res}))
}, [])
return (
<div>
<h1>Books</h1>
<div>
{state?.books?.length > 0 ? state?.books?.map( item => (<div>{item.name}</div>)) : '加载中'}
</div>
</div>
)
}
export default Books;
到此已经完成 使用useReduer 实现redux 了