今天教學結合了 useContext + useReducer,已經做到跟 redux 基本一樣的能力了,在小的項目使用綽綽有餘。
useContext教學:
- 建立 React.createContext()
//context.js import React from "react"; export const CatStateContext = React.createContext();
2. 利用 context 建立一個Provide 初始化 state,以供下面的子元素可以使用
利用 useReducer,建立管理 state的 action。
Provider這邊
const [state, dispatch] = useReducer(reducer, initialState);
Provider value = {[state, dispatch]}
//provider.js import React, { useReducer } from "react"; import Content from "./content"; import { CatStateContext } from "./context"; const initialState = { character: [ { id: "01", name: "湯姆貓", feature: "很蠢" }, { id: "02", name: "傑立鼠", feature: "很賤" }, { id: "03", name: "母湯貓", feature: "哥哥~母湯喔!" } ], startCatchMouse: false }; const reducer = (state, action) => { switch (action.type) { case "ADD_CONTACT": return { character: [...state.character, action.payload] //payload就是傳回來的資料 }; case "DEL_CONTACT": return { character: state.character.filter( (character) => character.id !== action.payload ) }; case "START": return { startCatchMouse: true }; case "COMPLETE": return { startCatchMouse: false }; default: throw new Error(); } }; export const ProviderContext = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <CatStateContext.Provider value={[state, dispatch]}> <Content /> </CatStateContext.Provider> ); };
3. 取得state值 跟 dispatch的方法
import context 後,使用React.useContext (context) 就可以開始取得值了
把要用到更新state的方法使用 dispatch({type: 對應的方法 , payload: 值})
就可以成功update到 context當初 初始化的state了
//content.js import React, { useContext } from "react"; import { CatStateContext } from "./context"; export default (props) => { const [state, dispatch] = useContext(CatStateContext); const delContact = (id) => { dispatch({ type: "DEL_CONTACT", payload: id }); }; const addContact = (event) => { dispatch({ type: "ADD_CONTACT", payload: { id: event.target.childNodes[0].childNodes[1].value, name: event.target.childNodes[1].childNodes[1].value, feature: event.target.childNodes[2].childNodes[1].value } }); event.preventDefault(); }; const table = state.character.map((value) => { return ( <div key={value.id} style={{ border: "1px solid green" }}> <p>編號 {value.id}</p> <h3>名字 {value.name}!</h3> <h3>特徵 {value.feature}</h3> <button onClick={() => delContact(value.id)}>刪除</button> </div> ); }); return ( <div> <form onSubmit={(e) => addContact(e)}> <p> id: <input required type="text" /> </p> <p> name <input required type="text" /> </p> <p> feature <input required type="text" /> </p> <button>新增</button> </form> {table} </div> ); };
主程式:
//index.js import React from "react"; import ReactDOM from "react-dom"; import { ProviderContext } from "./provider"; class App extends React.Component { constructor(props) { super(props); this.state = { name: "湯姆貓應徵表" }; this.action = null; } render() { return ( <div> <h1>{this.state.name}</h1> <ProviderContext /> </div> ); } } ReactDOM.render(<App />, document.getElementById("app"));
Demo:
@copyright MRcodingRoom
觀看更多文章請點MRcoding筆記
觀看更多文章請點MRcoding筆記