connect
- https://chentsulin.github.io/redux/docs/basics/UsageWithReact.html
- currying https://dev.to/brumor/programming-concepts-in-js-currying-34mc
const HomePage = ({state, action}) => {
return {
<button
onclick = {()=>{dispatch(action({data}))}}
>
call action
</button>
}
}
const mapStateToProps = (state) -> {
return state
}
const mapDispatchToProps = (dispatch) -> {
return dispatch
}
export default connect(mapStateToProps, mapDispatchToProps)(HomePage)
map 用來綁定資料流
<Provider store={store}>
<HomePage>
</Provider>
Provider 是 react-redux 提供的,跟 useContext 無關
example Todos
actions
export const getTodos = () => {
return (dispatch) => {
axios
.get(`${url}/todos`, setHeaders())
.then((todos) => {
dispatch({
type: "GET_TODOS",
todos,
});
})
.catch((error) => {
console.log(error);
});
};
};
export const addTodo = (newTodo) => {
return (dispatch, getState) => {
const author = getState().auth.name;
const uid = getState().auth._id;
axios
.post(`${url}/todos`, { ...newTodo, author, uid }, setHeaders())
.then((todo) => {
dispatch({
type: "ADD_TODO",
todo,
});
})
.catch((error) => {
console.log(error.response);
toast.error(error.response?.data, {
position: toast.POSITION.BOTTOM_RIGHT,
});
});
};
};
export const updateTodo = (updatedTodo, id) => {
return (dispatch) => {
axios
.put(`${url}/todos/${id}`, updatedTodo, setHeaders())
.then((todo) => {
dispatch({
type: "UPDATE_TODO",
todo,
});
})
.catch((error) => {
console.log(error);
toast.error(error.response?.data, {
position: toast.POSITION.BOTTOM_RIGHT,
});
});
};
};
export const deleteTodo = (id) => {
return (dispatch) => {
axios
.delete(`${url}/todos/${id}`, setHeaders())
.then(() => {
dispatch({
type: "DELETE_TODO",
id,
});
})
.catch((error) => {
console.log(error);
toast.error(error.response?.data, {
position: toast.POSITION.BOTTOM_RIGHT,
});
});
};
};
reducers
const todoReducer = (todos = [], action) => {
switch (action.type) {
case "GET_TODOS":
return action.todos.data;
case "ADD_TODO":
toast.success("A todo was added...", {
position: toast.POSITION.BOTTOM_RIGHT,
});
return [action.todo.data, ...todos];
case "UPDATE_TODO":
toast.success("A todo was updated...", {
position: toast.POSITION.BOTTOM_RIGHT,
});
return todos.map((todo) =>
todo._id === action.todo.data._id ? action.todo.data : todo
);
case "DELETE_TODO":
toast.success("A todo was deleted...", {
position: toast.POSITION.BOTTOM_RIGHT,
});
return todos.filter((todo) => todo._id !== action.id);
default:
return todos;
}
};
export default todoReducer;
通常指令會用變數,將所有 action type 用變數共同管理
// actions/todolist
export const ADD_TODO = 'ADD_TODO';