React

image.png

image.png

Umi官方文档地址

本篇文章主要介绍的一个 React小白,从 0 使用umi搭建React项目的过程,记录了相关umi的使用以及react的相关知识点~

目录:

持续更新中...

1.在 config 文件内配置 title 无效问题;
2.favicon页面头部小图标配置无效;
3.className 样式选中高亮,或者多个 className 存在;
4.路由跳转和参数接受;
5.useState 和 useEffect;
6.如何用 dva 定义一个 Model,并修改;
7.权限路由(根据用户登录状态,跳转登录页);
8.组件通信;
9.函数式组件调用(forwardRef, useImperativeHandlede);
10.在React中显示html模块内容
11.修改List列表中的某一个数值
12.request请求配置
13.受控组件空值警告解决
14.useState()异步问题处理
15.打包后修改输出文件目录 outputPath
16.如何使用sass
17.createElement 和 cloneElement的区别
18.路由按需加载,Loading
19.部署后页面不显示问题


1.在 config 文件内配置 title 无效问题

image.png

解决:如果你采用的是config方式,那就把默认的 .umirc.ts 文件删掉即可


2.favicon页面头部小图标配置无效
image.png

解决:采用links引入,favicon适合引入对应链接的图标


3.className 样式选中高亮,或者多个 className 存在

image.png

解决:参考地址

className={`nav ${index === '1' ? 'active' : ''}`}

4.路由跳转和参数接受
image.png
image.png

5.useState 和 useEffect

Hook概览,建议仔细阅读文档

image.png

image.png
这里会牵扯到 useEffect 后面有无 [] 的解释
    : 相当于 componentDidMount和componentDidUpdate,有点类似计算属性;
[]  : 相当于 componentDidMount 执行一次,用来请求数据;
[值]: 相当于把方法与这个值绑定,值发生改变时,就会调用该方法;


export default function IndexPage(props) {
  const [bannerList, setBannerList] = useState([])
  const [count, setCount] = useState(0)
  useEffect(() => {
     getBannerList().then(res=>{
       //储存轮播图数据
       setBannerList(res.data)
      })
  }, [])

  useEffect(()=>{
    //这里每次点击add按键就会返回
    console.log(count);
  })
  return (
    <>
      

寄内地

); }

6.如何用 dva 定义一个 Model,并修改

image.png

总而言之,这家伙有点类似于 vuex ,相当于用来处理全局数据的一个东西,希望下面的几个文章可以帮到你

  • dva概念
  • dva定义 Model
  • count模块定义案列
  • Redux 工具包快速入门

例子:
这是我简单写的一个切换用户名的Model案例
需要留意的地方我已经用 红色 标记出来了,尤其是 { } ,如果没有的话,默认会接受一个 props ,在路由页面传参中有提到

image.png

image.png

7.权限路由(根据用户登录状态,跳转登录页)

约定式路由,如果按照官方推荐的目录结构,是可以不用配置路由表的,它会自动生成

这里有两种写法,一种是放在route路由表里,另一种是直接在指定页面写,看个人需求。
写法1:wrappers
写法2:权限路由

image.png

8.组件通信

React 中组件间通信的几种方式
子用父:将数据绑定到子组件上,子组件通过props接收;

//父组件

...
//子组件调用
this.props.value

父用子:通过useRef()定义,并在子组件上绑定ref,.current获取DOM;

//父组件
const ziRef = useRef(null)

ziRef.current.state.{值}

子改父:通过在子组件上绑定一个关联父组件的方法数据

//父组件
{改值方法}} />
...
//子组件调用
this.props.onChange(值)

父改子:通过useRef()定义,并在子组件上绑定ref,.current调用子组件定义修改值的方法;

//父组件
const ziRef = useRef(null)

ziRef.current.onChange(值)
...
//子组件
onChange = (值)=>{
改值方法
}
9.函数式组件调用(forwardRef, useImperativeHandlede)

报错信息:
**Warning:**devScripts.js:6523 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

如果你在封装的组件上使用ref,那你就会发现这个错误,这就属于函数式调用,需要 useRef forwardRef的使用,同时还能配合 useImperativeHandlede 来暴露子组件的数值或者方法给父组件使用。
React函数式组件值之useRef()和useImperativeHandle()
React Hooks系列之useImperativeHandle

10.在React中显示html模块内容

React中的HTML转义写法

11.修改List列表中的某一个数值
const [list,handleList] = useState([])
...
{
list.map((val, index) => {
                            let arr = [...list]
                            arr[index] = '修改'
                            handleList(arr)
                        }}>点击修改list{index}的数值
)}
12.request请求配置

umi-request配置说明
本地端口号修改
如何获取后端的相应数据 data
src/utils/request.js

/** Request 网络请求工具 更详细的 api 文档: https://github.com/umijs/umi-request */
import { extend } from 'umi-request';
import { Toast } from 'antd-mobile';
const codeMessage = {
    200: '服务器成功返回请求的数据。',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队(异步任务)。',
};
/** 异常处理程序 */

const errorHandler = (error) => {
  const { response } = error;
  console.log(response);


  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;
    Toast.info({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    Toast.info({
      description: '您的网络发生异常,无法连接服务器',
      message: '网络异常',
    });
  }

  return response;
};
/** 配置request请求时的默认参数 */

const request = extend({
    // prefix: 'http://192.168.0.115',  //配置域名
    timeout: 3000, //请求超时时间
    headers: {},
    // errorHandler,
    // 默认错误处理
    credentials: 'include', // 默认请求是否带上cookie
});

// 请求拦截
request.interceptors.request.use((url, options) => {
     options.headers['Authorization'] = 'Bearer'
    return {
        url,
        options: { ...options, interceptors: true },
    };
});
// 响应拦截
request.interceptors.response.use(async (response) => {
  const data = await response.clone().json();
  if (data.code !== 200) {
    Toast.info(data.message)
  }
  return response;
});
export default request;

使用

import request from '@/utils/request';
export  function loginIn(data) {
    return request('/api/login/account', {
        method: 'POST',
        data,
    });
}
13.受控组件空值警告解决

官方文档解释

解决方法

//defaultValue 替换 `input` 上的 value

//or

image.png
14.useState()异步问题处理

使用 State Hook

下面的预期在某些时候并不是你想要的

const [num,handleNum] = useState(0)
...
useEffect(() => {
 handleNum(1)
 console.log(num) //0
 handleNum(2)
 console.log(num) //0
}, []);

例如:在移动端滑动加载更多 list,根据搜索条件去更新 list,每次条件的变化就需要重新让 list = [],然后再去获取新的 list,此时就会遇到这种 list 不能及时更新清空的问题

const [search,handleSearch] = useState('')
const [list,setList] = useState([])
获取list数据
const fetchList = ()=> {
  getList().then(res=>{
     setList(...list,...res.data)
   })
}
//根据筛选条件加载数据
useEffect(() => {
   setList([]) //设想每次变化时就清空 list
   fetchList() //但是在处理数据并没有及时清空 list
}, [search]);

解决:

...
//每次条件变化就会清空 list
useEffect(() => {
   setList([])
}, [search]);
//list发生变化就去调用接口数据
useEffect(() => {
 //判断当list为[]时,调用接口
 if(!list.length){
   fetchList()
  }
}, [list]);
15.打包后修改输出文件目录 outputPath

outputPath 配置
outputPath:dist/shunfeng,打包后会生成 dist文件下shunfeng文件下的其他文件

image.png

image.png

16.如何使用sass

umi中使用sass只需安装 @umijs/plugin-sass

yarn add @umijs/plugin-sass --D

安装完后无需配置,umi会自己识别。默认使用dart sass , 如果需要使用node-sass,才需要想官网那样 配置

17.createElement 和 cloneElement的区别

区别:传入的第一个参数不同

React.createElement()
它接受三个参数,第一个参数可以是一个标签名。如 div、span,或者 React 组件。第二个参数为传入的属性。第三个以及之后的参数,皆作为组件的子组件。

React.createElement(type, [props], [...children]);

React.cloneElement()
React.cloneElement()React.createElement()相似,不同的是它传入的第一个参数是一个 React 元素,而不是标签名或组件。新添加的属性会并入原有的属性,传入到返回的新元素中,而旧的子元素将被替换。将保留原始元素的键和引用。

React.cloneElement(element, [props], [...children]);
18.路由按需加载,Loading

配置 dynamicimport

export default {
  dynamicImport: {
    loading: '@/Loading', //Loading组件
  },
};
19.部署后页面不显示问题
  • publicpath

    image.png

  • base

    image.png

// 生产 测试配置
base: process.env.NODE_ENV === 'production' ? '/foo/' : '/',
publicPath: process.env.NODE_ENV === 'production' ? '/foo/' : '/',

你可能感兴趣的:(React)