简单看了下,这个规则要点是:redux
type是必须的,其余三个可选。规定action不能再有其余属性了。bash
不要经过相似GET_DATA_SUCCESS
和GET_DATA_FAIL
这样的type去处理错误。而是经过设置error:true处理app
{
type: 'GET_DATA',
payload: new Error(),
error: true
}
复制代码
redux-actions是建立各类actionCreater,action只是简写。调用生成的actionCreater函数才会产生真正的action。函数
例如oop
const a = createAction('INCREMENT');
console.log(a(111))
复制代码
产生的结果是ui
{
type: 'INCREMENT',
payload: 111
}
复制代码
const actionCreater = createAction('INCREMENT');
复制代码
const reducer = handleAction(
actionCreator,
(state, action) => ({
...state,
counter: state.counter + 1,
}),
{ counter: 1 }
);
复制代码
dispatch(actionCreater())
复制代码
经过以上三步,能够看出端倪了,可是并没什么用,咱们用redux的痛点是什么?一堆switch,dispatch时候type乱飞等。下面让咱们用redux-actions来实现经典官方例子todo。spa
actions
code
export const add = createAction('ADD_TODO');
export const del = createAction('DELETE_TODO');
export const toggle = createAction('TOGGLE_TODO');
复制代码
reducers
对象
const defaultState = [];
const reducer = handleActions({
[add]: (state, {payload}) => {
return [...state, {
text: payload,
done: false
}];
},
[del]: (state, {payload}) => {
const ind = state.findIndex(item => item.text === payload);
return [...state.slice(0, ind), ...state.slice(ind + 1)];
},
[toggle]: (state, {payload}) => {
const ind = state.findIndex(item => item.text === payload);
const todo = state[ind];
console.log(ind, todo)
return [
...state.slice(0, ind),
{
...todo,
done: !todo.done
},
...state.slice(ind + 1)
]
}
}, defaultState)
复制代码
组件
rem
function App() {
const [todo, setTodo] = useState('');
const dispatch = useDispatch();
const state = useSelector(state => state);
console.log('app');
function handleChange(e) {
setTodo(e.target.value);
}
function handleAdd() {
dispatch(add(todo));
setTodo('');
}
return (
<div className="App">
<input value={todo} onChange={handleChange} />
<button onClick={handleAdd}>Add</button>
<br />
<ul>
{state.map(({ text, done }) => (
<li key={text}>
<span
onClick={() => dispatch(toggle(text))}
style={done ? { textDecoration: 'line-through' } : null}
>
{text}
</span>
<button onClick={() => dispatch(del(text))}>X</button>
</li>
))}
</ul>
</div>
);
}
复制代码
定义action
const increment = createAction('INCREMENT')
复制代码
在reducer中引用
const reducer = handleActionsWithImmer({
[increment]: (state) => {
return state + 1;
},
...
复制代码
在组件中引用
dispatch(increment());
复制代码
const noop = createAction('NOOP');
const error = new TypeError('not a number');
noop(error);
复制代码
将自动生成一个error为true的action
{
type: 'NOOP',
payload: error,
error: true
}
复制代码
在reducer中,能够自行判断error为true做处理,也能够以下声明式处理。这样,正常action会走next处理,若是error为true的action会走throw处理
handleAction(noop, {
next(state, action) {
return action.payload;
},
throw(state, action) {
console.log('出错了', state, action);
return state;
}
}, 'xxxxx');
复制代码