useState 值为数组或对象
1. 值为数组,useState<Type[]>([])
2. 值为对象,初始值设为Null
type User = {
name: string;
};
const [user, setUser] = useState<User | null>(null);
结合可选链操作符就符合TS校验
props & children传值
const Icon = () => {
return <div>icon组件</div>;
};
const A: React.FC = () => {
return (
<>
<h2>A组件内容</h2>
<B comp={Icon}>
<C />
</B>
</>
);
};
type Props = {
children: React.ReactNode;
comp: React.ComponentType;
};
const B: React.FC<Props> = (props) => {
console.log(props);
return (
<>
<div>
<h3>B组件内容</h3>
<props.comp></props.comp>
<div>{props.children}</div>
</div>
</>
);
};
React 传插槽
const A: React.FC = () => {
const [num, setNum] = useState("点击输出");
return (
<>
<h2>A组件内容</h2>
<B type="primary" onClick={() => console.log("Click!!!")}>
<h4>{num}</h4>
</B>
</>
);
};
type Props = {
type: string;
onClick: () => void;
children: React.ReactNode;
};
const B: React.FC<Props> = (props) => {
console.log(props);
return (
<>
<div>
<h3>B组件内容</h3>
<div>{props.type}</div>
<button onClick={props.onClick}>{props.children}</button>
</div>
</>
);
};
useRef和createRef
const A: React.FC = () => {
const cRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
console.log("C", cRef.current);
}, []);
const handle = () => {
cRef.current!.handleNum();
};
return (
<>
<h2>A组件内容</h2>
<button onClick={handle}>C组件+1</button>
<C ref={cRef} a="prop文本"></C>
</>
);
};
const C: React.FC = forwardRef((props, ref) => {
const [num, setNum] = useState(11);
function handleNum() {
setNum(num + 1);
}
useImperativeHandle(ref, () => {
return {
num,
handleNum,
};
});
return (
<>
<div>
<h3>C组件内容:{num}</h3>
<button onClick={handleNum}>++</button>
</div>
</>
);
});
const timeId = useRef<{id: number}>(-1)
timeId.current.id = setTimeout(()=>{},1000)
useContext & createContext
import UserContext from "@/Context/UserContext";
type User = {
name: string;
age: number;
};
type List = {
id: number;
name: string;
};
const A: React.FC = () => {
const [info, setInfo] = useState<User>({ name: "", age: 0 });
const [list, setList] = useState<List[]>([]);
return (
<>
<UserContext.Provider value={{ ...info, list }}>
<h2>A组件内容</h2>
<C></C>
</UserContext.Provider>
</>
);
};
import { createContext } from "react"
type List = {
id: number
name: string
}
type UserContextType = {
name: string
age: number
list: List[]
}
const defaultValue:UserContextType = {
name: '',
age: 0,
list: []
// add:()=>void
}
const UserContext = createContext(defaultValue)
export default UserContext
import UserContext from "@/Context/UserContext";
import { useContext } from "react";
const C = () => {
const ctx = useContext(UserContext);
console.log(ctx);
return (
<>
<div>C组件</div>
<div>
<span>展示父组件的数据:</span>
<span>{ctx.name}</span>
<span>{ctx.age}</span>
{ctx.list?.map((item, index) => {
return <div key={index}>{item.name}</div>;
})}
</div>
</>
);
};
import { createContext } from "react";
type IContext = {
list: Array<IGoods> |undefined;
handleList:(id: number, type: string)=>void
handleList2: (id: number,val: number)=>void
}
const defaultVal = {
list:[],
handleList(){},
handleList2(){}
}
const GoodsContext = createContext<IContext>(defaultVal)
export default GoodsContext
const handleList2 = (id: number, val: number) => {
const item = list.find((item) => item.id === id);
item!.count = val;
setList([...list]);
};
<GoodsContext.Provider value={{ list, handleList, handleList2 }}>
// 把setList放到函数里,上面这种传方法,就能直接更改数据
React-Redux & Toolkit
import { Provider } from "react-redux";
import store from "../../store/index";
const A: React.FC = () => {
return (
<>
<Provider store={store}>
<h2>A组件内容</h2>
<C></C>
</Provider>
</>
);
};
import { createSlice } from "@reduxjs/toolkit";
const userStore = createSlice({
name: 'user',
initialState:{
name: '未命名',
age: 20,
infos: [1,2,3]
},
reducers:{
handleName(state, action){
console.log('action', action);
state.name = action.payload.name
},
handleAge(state, action){
const {type, num} = action.payload
switch(type){
case 'add':
state.age +=num;
break;
case 'del':
state.age -=num;
break;
default:
state.age;
break;
}
},
handleInfo(state, action){
state.infos = [...state.infos, action.payload]
}
}
})
export const {handleName, handleAge, handleInfo} = userStore.actions
export default userStore.reducer
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "./module/userStore";
const store = configureStore({
reducer: {
userReducer
}
})
export default store
import { useSelector, useDispatch } from "react-redux";
import { handleName, handleAge, handleInfo } from "@/store/module/userStore";
type UserReducer = {
userReducer: {
name: string;
age: number;
};
};
const C = () => {
const { name, age, infos } = useSelector(
(state: UserReducer) => state.userReducer
);
const dispatch = useDispatch();
const handleSyncName = (name: string) => {
dispatch(handleName({ name }));
};
const handleSyncAge = (type: "del" | "add", num: number) => {
dispatch(handleAge({ type, num }));
};
const handleSyncInfo = (info: []) => {
dispatch(handleInfo(info));
};
return (
<>
<div>C组件</div>
<h2>toolkit内容</h2>
<div>
<div>姓名:{name}</div>
<div>年龄:{age}</div>
{infos.map((item, i) => {
return <div key={i}>值{item}</div>;
})}
</div>
</>
);
};
React-Router-DOM V6
const routerConfig = createBrowserRouter([
{ path: "/", element: <Navigate to="/Login"></Navigate> },
{ path: "/login", element: <Login /> },
{
path: "/main",
element: <Main />,
children: [{ index: true, element: <MainSon /> }],
},
{ path: "*", element: <NotFound /> },
]);
<RouterProvider router={routerConfig}></RouterProvider>
const Main: React.FC = () => {
const navigate = useNavigate();
const [params] = useSearchParams();
const _id = params.get("id");
const paramsObj = useParams();
const gotoLogin = () => {
navigate("/login");
};
const [name, setName] = React.useState("父组件数据");
return (
<>
<h3>Main组件</h3>
<div>
<button onClick={gotoLogin}>去Login</button>
<div>
<p>SearchParams:{_id}</p>
<p>{paramsObj.v}</p>
</div>
<h4>二级路由展示区</h4>
<hr />
<Outlet context={[name, setName]} />
</div>
</>
);
};
const Login: React.FC = () => {
const navigate = useNavigate();
const [id, setId] = useState(99);
const [name, setName] = useState("张三");
const gotoMain = () => {
navigate(`/main?id=${id}`);
};
const gotoMain2 = () => {
navigate(`/main/${name}`);
};
return (
<>
<h3>Login组件</h3>
<div>
<button onClick={gotoMain}>去Main</button>
<button onClick={gotoMain2}>去Main2</button>
</div>
</>
);
};
const MainSon: React.FC = () => {
const [name, setName] = useOutletContext();
return (
<>
<p>{name}</p>
<button onClick={() => setName("lisi")}>修改</button>
</>
);
};
useReducer 用法
type Action = {
type: "ADD" | "DEL";
payload: number;
};
function countReducer(state: number, action: Action) {
switch (action.type) {
case "ADD":
return state + action.payload;
case "DEL":
return state - action.payload;
default:
return state;
}
}
const A1: React.FC = () => {
const [count, dispatch] = useReducer(countReducer, 0);
function handleCount(type: Action["type"], num: number) {
dispatch({ type, payload: num });
}
return (
<>
<h2>{count}</h2>
<button onClick={() => dispatch({ type: "ADD", payload: 100 })}>
操作+
</button>
</>
);
};