The React project uses custom Hook+useContext for state management.

Customize the Hook

A custom Hook must start with use, or React syntax checks will not let you pass. Because useState of React is stored sequentially in a linked list during function execution, custom hooks can only be called at the first level of the function. Do not put it in the condition judgment, because the condition will affect the execution order of useState, which will affect the storage order of the linked list.

Code sample

Use custom hooks to encapsulate a set of operations on record as a custom Hook function. Data is stored in useState. And expose a series of methods of operating state. You can do multiple functions similar to Vue

// Define the record type
export type RecordItem={
	id:number
    tagId:number
    note:string
    createdAt:string
}

// Define the type returned by useRecord
export type RecordAction = {
	records:RecordItem[]
	createRecord:(record: RecordItem) = >void
    deleteRecord:(id: number) = >void
    updateRecord:(id: number, record: RecordItem) = >void
    findRecord:(id: number) = >void
}

const useRecords = (): RecordAction= > {
  const [records, setRecords] = useState<RecordItem[]>(recordList);
  / / to add
  const createRecord = (record: RecordItem) = > {
    if(! record.createAt)// Use dayJS formatting to record the creation time
      record.createAt = dayjs(new Date()).format('YYYY-MM-DDTHH:mm:ss');
    record.id = createId(); / / generated ID
    setRecords((rs) = > [...rs, record]);
  };
  / / delete
  const deleteRecord = (id: number) = > {
    setRecords((rs) = > rs.filter((r) = >r.id ! == id)); };/ / change
  const updateRecord = (id: number, record: RecordItem) = > {
    setRecords((rs) = > rs.map(r= >r.id === id ? {id, ... record} : r)); };/ / check
  const findRecord = (id: number) = > {
    return records.filter((r) = > r.id === id)[0];
  };
  return{createRecord, deleteRecord, updateRecord, findRecord, records}}export default useRecords
Copy the code

This allows you to use useRecord in your project to manage the state of the records.

Note that you need to ensure that the entire project useReacord is called only once. After all, useReacord is only a function. Each call creates a new state.

To call useRecord only once, you can use useContext to pass the object returned by useRecord() from the topmost component (the method that operates on Records) to the child component.

context.tsx

import {createContext} from 'React'
import {RecordAction} from 'hooks/useRecord' //createContext accepts the type
const ContextReacrd = createContext<RecordAction>({}) 
export default ContextRecord
Copy the code

App.tsx

import React from 'react' import ContextRecord from '/.. /ContextRecord' import useRecord from 'hooks/useRecord' const App = ()=>{ const recordAction = useRecord() Provider value={recordAction}> <Child /> </ contextRecord.provider >)}Copy the code

This way you can use useContext in a descendant component to get a function that operates on state.

Child.tsx

import React,{useContext} from 'react' import ContextRecord from '/.. /ContextRecord' const Child = ()=>{const recordAction = useContext(ContextRecord) return (<Child2 />) } export default ChildCopy the code