react+umijs学习记录
·
文章目录
1.useEffect
不带依赖 每次都会执行
[] 只执行一次
[userid] userid变化的时候会执行
多个useEffect 依次执行
useEffect(() => {
if (dispatch) {
// 获取数据字典数据,项目类型,项目状态
const types: string[] = ['project_type']
// eslint-disable-next-line no-restricted-syntax
for (const key of types) {
if (!dict[key].length) {
dispatch({
type: 'dictionary/fetchDict',
code: key,
})
}
}
}
}, [])
2.useState
setModalVisible异步的 减少dom操作
const [modalVisible, setModalVisible] = useState(false)
3.封装一个Modal 表单
import React, { useState } from 'react'
import { Modal, Form, Input, InputNumber, Select, Row, Col, message } from 'antd'
interface RandomQuestionModalProps {
visible: boolean
onClose: () => void
}
// 表单字段类型定义
interface FormValues {
name: string
questionCount: number
difficulty: 'easy' | 'medium' | 'hard' | 'mixed'
timeLimit: number
questionType: string[]
description?: string
}
const RandomQuestionModal: React.FC<RandomQuestionModalProps> = ({ visible, onClose }) => {
const [form] = Form.useForm()
const [loading, setLoading] = useState(false)
// 表单提交
const handleSubmit = async () => {
try {
setLoading(true)
// 验证并获取表单值
const values = await form.validateFields()
// 构造提交数据
// const projectData = {
// name: values.name,
// status: 0,
// type: 8, // 随机问卷类型
// description: values.description || '',
// questionCount: values.questionCount,
// difficulty: values.difficulty,
// timeLimit: values.timeLimit,
// questionTypes: values.questionType,
// }
// // 调用API创建项目
// const res = await addProject(projectData, 'add_project')
// // 成功处理
// message.success('项目创建成功')
// form.resetFields() // 重置表单
onClose() // 关闭弹窗
} catch (error) {
message.error('项目创建失败,请重试')
console.error('创建项目失败:', error)
} finally {
setLoading(false)
}
}
const handleCancel = () => {
onClose()
}
return (
<Modal
title="随机题目考试设置"
open={visible}
onOk={handleSubmit}
onCancel={handleCancel}
maskClosable={false}
confirmLoading={loading}
destroyOnClose
width={600}
>
<Form
form={form}
layout="vertical"
initialValues={{
difficulty: 'medium',
questionCount: 10,
timeLimit: 30,
}}
>
<Form.Item
name="name"
label="项目名称"
rules={[
{ required: true, message: '请输入项目名称' },
{ max: 50, message: '名称不能超过50个字符' },
]}
>
<Input placeholder="请输入项目名称" />
</Form.Item>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="questionCount"
label="题目数量"
rules={[
{ required: true, message: '请输入题目数量' },
{ type: 'number', min: 5, max: 100, message: '题目数量应在5-100之间' },
]}
>
<InputNumber min={5} max={100} style={{ width: '100%' }} placeholder="请输入数量" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="timeLimit"
label="时间限制(分钟)"
rules={[
{ required: true, message: '请输入时间限制' },
{ type: 'number', min: 5, message: '时间限制不能少于5分钟' },
]}
>
<InputNumber min={5} style={{ width: '100%' }} placeholder="请输入时间" />
</Form.Item>
</Col>
</Row>
<Form.Item
name="difficulty"
label="难度级别"
rules={[{ required: true, message: '请选择难度级别' }]}
>
<Select placeholder="请选择难度级别">
<Select.Option value="easy">简单</Select.Option>
<Select.Option value="medium">中等</Select.Option>
<Select.Option value="hard">困难</Select.Option>
<Select.Option value="mixed">混合</Select.Option>
</Select>
</Form.Item>
<Form.Item name="description" label="项目描述">
<Input.TextArea rows={4} placeholder="请输入项目描述(可选)" />
</Form.Item>
</Form>
</Modal>
)
}
export default RandomQuestionModal
使用
const [modalVisible, setModalVisible] = useState(false)
<RandomQuestionModal visible={modalVisible} onClose={() => setModalVisible(false)} />
4.useModel
Umi 框架内置了 useModel Hooks,用于访问通过 src/models 定义的全局模型数据,实现跨组件状态共享。
例如models 中
import { getQuestionTreeList } from '@/services/list'
import { useState, useEffect } from 'react'
import { history } from 'umi'
// export interface IQuestionTypeItem {
// createDate: string
// createName: string
// id: string
// orderNum: number
// remark?: string
// typeCode: string
// typeGroupId: string
// typeName: string
// typeValue?: string
// }
export interface IQuestionTypeItem {
childList: IQuestionTypeItem[] | null
code: string
id: string
name: string
parentCode: string
parentId: string
}
export default function useQuestionTypes() {
const [questionTypes, setQuestionTypes] = useState<IQuestionTypeItem[]>([])
useEffect(() => {
;(async () => {
// 如果是公开项目则不请求该接口
if (history.location.query?.public) {
return
}
// todo ts
// const ret: IQuestionTypeItem[] = await queryDataDictionary(
// 'question_bank_type',
// )
// 获取题库列表树
const ret: IQuestionTypeItem[] = await getQuestionTreeList('question_bank_type')
setQuestionTypes(ret)
})()
}, [])
return {
questionTypes,
}
}
使用
import { useModel } from 'umi'
const { questionTypes } = useModel<any>('useQuestionTypes')
5.循环渲染
<Select
placeholder="请选择题目类型"
mode="multiple"
style={{ width: '100%' }}
>
{questionTypes.map(type => (
<Select.Option key={type.value} value={type.value}>
{type.label}
</Select.Option>
))}
</Select>
6.条件判断显示隐藏
{isShow ? <div>这是要显示的内容</div> : null}
if语句
if (isShow) {
content = <div>这是要显示的内容</div>;
}
return <div>{content}</div>;
样式
<div
style={{
display: isShow ? 'block' : 'none', // 显示/隐藏
width: 100,
height: 100,
background: 'red'
}}
>
内容
</div>
7.createContext 配合 useContext 多层传递数据
创建 context.ts
import { createContext } from 'react'
export const DictContext = createContext({})
使用 数据dict共用
import { DictContext } from '@/context'
<DictContext.Provider value={dict}>
子组件1
子组件1
子组件1
</DictContext.Provider>
子组件获取
import { DictContext } from '@/context'
import React, { useState, useContext } from 'react'
const dict = useContext(DictContext)
8获取路由参数
import { connect, history, useModel } from 'umi'
history.location.query
更多推荐
所有评论(0)