注意:useReducer改变state,是会更新页面的
image.png
1. 创建初始值
const initial = {
n: 0
}
2. 创建所有操作
const reducer = (state, action) => {
if (action.type === 'add') {
return {n: state.n + action.number}
} else if (action.type === 'multi') {
return {n: state.n * 2}
} else {
throw new Error('unknown type')
}
}
3. 传给useReducer
const App = props => {
const [state, dispatch] = useReducer(reducer, initial)
const onClick = ()=>{
dispatch({type:'add',number:1})
}
const onClick2 = ()=>{
dispatch({type:'add',number:2})
}
return (
<div>
<h1>{state.n}</h1>
<button onClick={onClick}>+1</button>
<button onClick={onClick2}>+2</button>
</div>
)
}
- 模块化:
import React, {useState, useContext, useReducer, createContext, useEffect} from 'react'
const store = {
user: null,
books: null,
movies: null
}
const obj = {
'setUser': (state, action) => {
return {...state, user: action.user}
},
'setBooks': (state, action) => {
return {...state, books: action.books}
},
'setMovies': (state, action) => {
return {...state, movies: action.movies}
}
}
// 牛比
const reducer = (state, action) => {
/*switch (action.type) {
case 'setUser':
return {...state, user: action.user}
case 'setBooks':
return {...state, books: action.books}
case 'setMovies':
return {...state, movies: action.movies}
default:
throw new Error()
}*/
const fn = obj[action.type]
if (fn) {
// fn执行得到的是一个对象,因此加 return 的意思是要把这个对象返回出去。
// 不加的话是仅仅得到,不会在这个函数里返回的
return fn(state, action)
} else {
throw new Error('unknown type')
}
}
const Context = createContext(null)
const App = () => {
const [state, dispatch] = useReducer(reducer, store)
return (
<Context.Provider value={{state, dispatch}}>
<User/>
<hr/>
<Books/>
<Movies/>
</Context.Provider>
)
}
const User = () => {
const {state, dispatch} = useContext(Context)
useEffect(() => {
console.log('state');
console.log(state);
ajax('/user').then(res => {
console.log('res');
console.log(res);
dispatch({
type: 'setUser',
user: res.name
})
})
}, [])
return (
<div>
<h1>个人信息</h1>
<div>
name:{state.user ? state.user : ''}
</div>
</div>
)
}
const Books = () => {
return (
<div>
<h1>我的书籍</h1>
</div>
)
}
const Movies = () => {
return (
<div>
<h1>我的电影</h1>
</div>
)
}
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: "恋恋笔记本"
}
]);
}
}, 1000);
});
}
export default App
网友评论