当前位置:   article > 正文

Day08React——第八天

Day08React——第八天

useEffect

概念:useEffect 是一个 React Hook 函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAx请求,更改daom等等

需求:在组件渲染完毕后,立刻从服务器获取频道列表数据并显示到页面

语法:useEffect( ()=>{},[] )

参数1是一个函数,可以把它叫做副作用函数,在函数内部可以放置要执行的操作

操作2是一个数组(可选参),在数组里放置依赖项,不同依赖项会影响第一个参数函数的执行,当是一个空数组的时候,副作用函数只会在组件渲染完毕之后执行一次

React 18 中的 useEffect hook 没有依赖项时,表示该 effect 不依赖于任何状态或 props 的变化,只在组件挂载和卸载时执行一次。这与 React 17 中的类式组件中 componentDidMount 和 componentWillUnmount 生命周期方法的功能类似。

当 useEffect hook 中传入一个空数组作为依赖项时,表示该 effect 只在组件挂载时执行一次,类似于 React 17 中的 componentDidMount 生命周期方法。

而当 useEffect hook 中传入特定的依赖项时,表示该 effect 会在这些依赖项发生变化时执行。这与 React 17 中类式组件中 componentDidUpdate 生命周期方法的功能类似,可以根据特定的依赖项来触发 effect 的执行。

  1. export default function App() {
  2. const [count, updateCount] = useState(0);
  3. // 空数组依赖项 componentDidMount 只在初始化渲染一次
  4. useEffect(() => {
  5. async function getList() {
  6. const res = await fetch(URL);
  7. const jsonRes = await res.json();
  8. console.log(jsonRes);
  9. }
  10. getList();
  11. }, []);
  12. //没有依赖项 componentDidMount 初始渲染和组件更新时执行
  13. useEffect(() => {
  14. console.log(99999);
  15. });
  16. // 添加特点依赖项 componentDidUpdate
  17. useEffect(() => {
  18. console.log("couont 更新了");
  19. }, [count]);
  20. return (
  21. <div>
  22. App
  23. <div>{count}</div>
  24. <button
  25. onClick={() => {
  26. updateCount(count + 1);
  27. }}
  28. >
  29. +1
  30. </button>
  31. </div>
  32. );
  33. }

清除副作用

在useEffect 中编写的由渲染本身引起的对接组件外部的操作,叫做副作用模式,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器卸载掉,这个过程就是清理副作用

  1. //清除副作用
  2. function Zi() {
  3. useEffect(() => {
  4. const timer = setInterval(() => {
  5. console.log("打印中......");
  6. }, 1000);
  7. return () => {
  8. clearInterval(timer);
  9. };
  10. }, []);
  11. return <div>this is Zi component</div>;
  12. }
  13. export default function App() {
  14. const [show, ifShow] = useState(true);
  15. return (
  16. <div>
  17. App
  18. {show && <Zi />}
  19. <button
  20. onClick={() => {
  21. ifShow(false);
  22. }}
  23. >
  24. 卸载组件
  25. </button>
  26. </div>
  27. );

自定义 hook

概念:自定义Hook 是use打头的函数,通过自定义hook函数实现逻辑的封装复用

封装自定义hook思路:

  1. 声明一个以use打头的函数
  2. 把函数体内可复用的逻辑(只要是可复用的逻辑)
  3. 把组件中用到的状态或方法回调return出去
  4. 组件调用结构赋值
  1. function useShow() {
  2. const [show, updateShow] = useState(true);
  3. const ifShow = () => {
  4. updateShow(!show);
  5. };
  6. return {
  7. show,
  8. ifShow,
  9. };
  10. }
  11. export default function App() {
  12. const { show, ifShow } = useShow();
  13. console.log(show);
  14. return (
  15. <div>
  16. {show && <div>this is app</div>}
  17. <button onClick={ifShow}>click</button>
  18. </div>
  19. );
  20. }

Redux

Redux 是React最常用的集中状态管理工具,类似于Vue中的Pinia(Vuex),可以独立于框架运行 作用:通过集中管理的方式管理应用的状态

基本使用

子模块

  1. import {createSlice} from '@reduxjs/toolkit'
  2. const counterStore = createSlice({
  3. // 模块名
  4. name: "counter",
  5. // 初始数据
  6. initialState: {
  7. count: 0,
  8. },
  9. // 修改数据的同步方法
  10. reducers: {
  11. addCount(state) {
  12. state.count++;
  13. },
  14. saveCount(state) {
  15. state.count--;
  16. },
  17. },
  18. });
  19. // 结构出actionCreater
  20. const { addCount, saveCount } = counterStore.actions
  21. //获取redcer 函数
  22. const reducer = counterStore.reducer;
  23. // 导出
  24. export {addCount,saveCount}
  25. export default reducer;

index.js 模块总入口

  1. import { configureStore } from "@reduxjs/toolkit";
  2. import counterReducer from "./modules/counterStore";
  3. export default configureStore({
  4. reducer: {
  5. // 注册子模块
  6. counter: counterReducer,
  7. },
  8. });

index.js 将store注入react中

  1. import React from "react";
  2. import ReactDOM from "react-dom/client";
  3. import App from "./App";
  4. import { Provider } from "react-redux";
  5. import store from "./store";
  6. const root = ReactDOM.createRoot(document.getElementById("root"));
  7. root.render(
  8. // 使用中间件链接 将store注入 react中
  9. <Provider store={store}>
  10. <App />
  11. </Provider>
  12. );

app.js 页面组件使用

  1. import React from 'react'
  2. import { useSelector, useDispatch } from "react-redux";
  3. import { addCount, saveCount } from "./store/modules/counterStore.js";
  4. export default function App() {
  5. // 通过useSelector获取 store上的数据
  6. const { count } = useSelector((state) => state.counter);
  7. // 提交action传参
  8. const actions = useDispatch();
  9. return (
  10. <div>
  11. <button
  12. onClick={() => {
  13. actions(saveCount());
  14. }}
  15. >
  16. -
  17. </button>
  18. <div>{count}</div>
  19. <button
  20. onClick={() => {
  21. actions(addCount());
  22. }}
  23. >
  24. +
  25. </button>
  26. </div>
  27. );
  28. }

redux 同步方法参数

在reducers的同步修改方法中添加action对象参数,在调用actionCreater的时候传递参数,参数会被传递到action对象payload属性上

  1. const counterStore = createSlice({
  2. // 模块名
  3. name: "counter",
  4. // 初始数据
  5. initialState: {
  6. count: 0,
  7. },
  8. // 修改数据的同步方法
  9. reducers: {
  10. addCount(state, options) {
  11. state.count += options.payload;
  12. },
  13. saveCount(state, options) {
  14. state.count -= options.payload;
  15. },
  16. },
  17. });

异步方法

创建模块

  1. import { createSlice } from "@reduxjs/toolkit";
  2. import axios from "axios";
  3. const channeStore = createSlice({
  4. // 模块名
  5. name: "channe",
  6. // 初始数据
  7. initialState: {
  8. list: [],
  9. },
  10. reducers: {
  11. getList(state, options) {
  12. state.list = options.payload;
  13. },
  14. },
  15. });
  16. // 结构出actionCreater
  17. const { getList } = channeStore.actions;
  18. async function asyncGetList(actions) {
  19. const {
  20. data: {
  21. data: { channels },
  22. },
  23. } = await axios.get("http://geek.itheima.net/v1_0/channels");
  24. actions(getList(channels));
  25. }
  26. //获取redcer 函数
  27. const reducer = channeStore.reducer;
  28. // 导出
  29. export { asyncGetList };
  30. export default reducer;

app页面上使用

  1. export default function App() {
  2. const actions = useDispatch();
  3. useEffect(() => {
  4. asyncGetList(actions);
  5. }, []);
  6. return (
  7. <div>
  8. <ul>
  9. {list.map((i) => {
  10. return <div key={i.id}>{i.name}</div>;
  11. })}
  12. </ul>
  13. </div>
  14. </div>
  15. );
  16. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号