1.React useHistory 更新为useNavigate如何传值
路由组件如何传值
1.组件跳转并传值
(1)导入
代码语言:javascript复制import { useNavigate } from ‘react-router-dom’;
(2)使用
代码语言:javascript复制const navigate = useNavigate();
点击事件中使用
组件“/machine”为已经定义好的路由,state负责传值state:{参数:值}
代码语言:javascript复制 navigate('/machine', {
state: {
from: '1'
}
})
(3)获取值
代码语言:javascript复制导入import { useLocation } from ‘react-router-dom’;
使用
代码语言:javascript复制let location = useLocation();
let server_id = location.state;
2.封装公共dialog的小技巧(children props使用)
首先独立封装一个antd的dialog
代码语言:javascript复制import React, { useState } from 'react';
import { Modal, Button } from 'antd';
import CommonStyle from '../../../resources/styles/common.module.css'
const Dialog = (props: any) => {
console.log(props)
const { children } = props
const [isModalVisible, setIsModalVisible] = useState(true);
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
return (
<>
<Modal footer={null} visible={isModalVisible} onOk={handleOk} onCancel={handleCancel} closable={false}>
{children}
{/* <div className={CommonStyle.modalNav}>
<span className={`${CommonStyle.modalNavTitle}`}>
<img className={`${CommonStyle.modalNaviImage}`} src="https://pickkiwi.s3.amazonaws.com/upload/ly1sYz9aM986CwIOOCQ6Kwxx2vSxJK5eOia16D8x6nLO7cWTDTk7jKSwCl3bj-Ku2AGKSd7l" alt="" />
Request Product
</span>
<span className={`${CommonStyle.modalNavClose}`}><span className={`iconfont icon-exit ${CommonStyle.modalNavCloseIcon}`}></span></span>
</div> */}
</Modal>
</>
)
}
export default Dialog
然后在外面进行引用:
代码语言:javascript复制 <Dialog>
<div className={CommonStyle.modalNav}>
<span className={`${CommonStyle.modalNavTitle}`}>
<img className={`${CommonStyle.modalNaviImage}`} src="https://pickkiwi.s3.amazonaws.com/upload/ly1sYz9aM986CwIOOCQ6Kwxx2vSxJK5eOia16D8x6nLO7cWTDTk7jKSwCl3bj-Ku2AGKSd7l" alt="" />
Request Product
</span>
<span className={`${CommonStyle.modalNavClose}`}><span className={`iconfont icon-exit ${CommonStyle.modalNavCloseIcon}`}></span></span>
</div>
</Dialog>
组件包裹的部分,
可以使用this.props.children来获取并显示
代码语言:javascript复制const { children } = props
<Modal footer={null} visible={isModalVisible} onOk={handleOk} onCancel={handleCancel} closable={false}>
{children}
</Modal>
3.使用antd-form的内嵌组件(包括验证)
我们的想要的效果图:
代码:
代码语言:javascript复制 <Form
name="basic"
layout="vertical"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Desired Cost"
>
<Input.Group compact>
<Form.Item
name={['DesiredCost', 'cost']}
noStyle
rules={[{ required: true, message: 'desiredCost is required' }]}
>
<Input style={{ width: 365 }} placeholder="$10.00" />
</Form.Item>
<Form.Item
name={['DesiredCost', 'currency']}
noStyle
rules={[{ required: true, message: 'currency is required' }]}
>
<Select style={{ width: 100, marginLeft: 2 }}>
{currencyOpts.map((opt: any, index: any) => <Option key={index} value={opt.value}>{opt.label}</Option>)}
</Select>
</Form.Item>
</Input.Group>
</Form.Item>
</Form>
其实就是Form.Item里面套一个Input.group
然后再套Form.item就可以了,验证独自给form.item加上rules即可
参考文档:https://ant.design/components/form-cn/#header
4.重置antd-form
创建一个ref
代码语言:javascript复制 const formRef: any = React.createRef()
挂载到form上(我的组件是通过子组件传值过去的)
传递给子组件
代码语言:javascript复制 <RequestForm formRef={formRef} product={product} closeModal={closeModal} />
挂载
代码语言:javascript复制 <Form
ref={formRef}
>
关闭dialog时重置表单(父组件方法)
代码语言:javascript复制 const closeModal = () => {
console.log(formRef)
formRef.current.resetFields()
setVisible(false)
}
参考地址:https://blog.csdn.net/wsh2467991332/article/details/113850917
5.hook的useEffect 实现class的componentWillReceiveProps
代码语言:javascript复制 useEffect(() => {
_getRequests()
}, [filterArgs])
filterArgs就是我们要传递的Props,如果这个传递的值更新了 就会触发UseEffect
小技巧:
一个hooks里面可以写多个useEffect
来处理不同的方法
代码语言:javascript复制 useEffect(() => {
_getRecentRequests()
}, [])
useEffect(() => {
_getRequests()
}, [filterArgs])
6.antd的上传组件 实现自定义上传(类似于element的自定义上传文件)
关键api:customRequest
上代码:
首先是elementUI的自定义上传代码(关注:http-request):
组件部分:
代码语言:javascript复制 <el-upload
action
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:http-request="setBase"
accept=".jpg, .jpeg, .png, .gif, .JPG, .JPEG, .GIF"
:limit="1"
>
<i class="el-icon-plus"></i>
</el-upload>
方法:
代码语言:javascript复制 setBase(e) {
// el-upload上传的图片是blob对象 把它转为为base64再进行上传 e.file是blob对象
let params = new FormData();
params.append("file", e.file);
upload(params).then(res => {
if (res.data) {
this.title = e.file.name;
this.IMGArr.push({
name: res.data.filename,
uid: e.file.uid
});
}
});
},
结束 就这么简单
然后是antd的自定义上传设置
首先是组件:(关注customRequest部分)
代码语言:javascript复制 <Upload
listType="picture-card"
fileList={fileList}
customRequest={this.handleChange}
>
<div className={Styles.uploadBtnHide} id="uploadBtnHide">Add Images</div>
</Upload>
然后是方法拿到文件,然后就传递吧 下课!
代码语言:javascript复制 handleChange = (event: any) => {
console.log(event.file)
}
完整的react antd组件上传demo
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/antd/4.18.8/antd.min.css
"
/>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/antd/4.18.8/antd.min.js"></script>
<style>
#uploadBtn {
display: none;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<style></style>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
testVal: "123",
fileList: [],
};
}
render() {
console.log(this);
let { fileList } = this.state;
return (
<h1>
<div id="uploadBtn">
<antd.Upload
listType="picture-card"
customRequest={this.handleChange}
>
<antd.Button id="clickUploads"></antd.Button>
</antd.Upload>
</div>
<antd.Button onClick={this.clickUpload}>
Click to Upload
</antd.Button>
文件列表:
<div>
{fileList.map((item, index) => (
<antd.Image width={200} key={index} src={item} />
))}
</div>
</h1>
);
}
handleChange = (event) => {
console.log(event.file);
let { fileList } = this.state;
const fd = new FormData();
fd.append("file", event.file);
fetch("http://biaoblog.run:3000/blogData/upload", {
headers: {
authorization:
"Bearer xxx",
},
body: fd,
method: "POST",
})
.then((res) => res.json())
.then((res) => {
console.log(res.filename);
console.log(fileList);
let newFileList = fileList;
newFileList.push(res.filename);
this.setState({
fileList: newFileList,
});
console.log();
});
};
clickUpload = () => {
document.querySelector("#clickUploads").click();
};
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</html>
7.antd-form中自动获取checkbox组件的值
需要在chekbox中添加一个属性:
valuePropName="checked"
代码语言:javascript复制 <Form
ref={formRef}
name="basic"
layout="vertical"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
name="accept_similar"
valuePropName="checked"
>
<Checkbox>Accept similar products</Checkbox>
</Form.Item>
<Form>
8.react-redux 持久化 仓库配置(包含thunk)
代码语言:javascript复制import { applyMiddleware, createStore } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunkMiddleware from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from '../reducer'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer())
const store = createStore(persistedReducer, composeWithDevTools(applyMiddleware(thunkMiddleware)))
export const persistor = persistStore(store)
export default store
然后在App.js中进行引入
代码语言:javascript复制import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/es/integration/react'
import store, { persistor } from './redux/store/index'
import AppRouter from './router'
function App() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<AppRouter />
</PersistGate>
</Provider>
)
}
export default App
然后往仓库存储一个数据,刷新,发现持久化Ok了,下课
9.在react-hook中获取到redux仓库中的值(封装了thunk)
跟class的写法一样(前提是封装thunk)
先引用:
代码语言:javascript复制import { connect } from 'react-redux'
然后使用:
代码语言:javascript复制function mapStateToProps(state: any) {
return {
userInfo: state.app.currentUser.user
}
}
export default connect(mapStateToProps)(AccountIndex);
然后在组件中获取:
代码语言:javascript复制const AccountIndex = (props: any) => {
console.log(props.userInfo) // props.userInfo就是仓库里面的数据
return <Container>
</Container>
}
结束!
10.一个Input的动态样式,可以参考
unclick:
click:
非常简单,想复杂了
11.antd-form 自定义校验
需求就是我们的验证码组件需要校验
可以用到form的自定义检验(就是拿到form的value和验证码 进行对比 然后抛错,挺方便)
代码语言:javascript复制 <Form.Item
name={["user", "code"]}
label="验证码"
rules={[
{ required: true },
({ getFieldValue }) => ({
validator(_, value) {
console.log(SIdentifyRef);
if (value == SIdentifyRef.current.state.code) {
return Promise.resolve();
}
return Promise.reject(new Error("验证码错误"));
},
}),
]}
style={{ width: 300 }}
>
<Row gutter={16}>
<Col className="gutter-row" span={18}>
<Input style={{ width: 200 }} />
</Col>
<Col className="gutter-row" offset={1} span={2}>
<SIdentify ref={SIdentifyRef} />
</Col>
</Row>
</Form.Item>
12.一个href的动画css效果
html
代码语言:javascript复制 <a href="11111">哈哈哈哈</a>
css
代码语言:javascript复制 a {
text-decoration: none;
border-bottom: 1px solid;
border-bottom-color: #00000026;
position: relative;
display: inline-block;
color: black;
}
a:after {
content: "";
position: absolute;
bottom: -2px;
left: 0;
width: 0%;
border-bottom: 2px solid currentColor;
transition: width 0.5s ease;
}
a:hover:after {
width: 100%;
}
13.使用useMediaQuery来判断pc和mobile
代码语言:javascript复制import useMediaQuery from '@/hooks/useMediaQuery'
const Login = () => {
const isMobile = useMediaQuery('(max-width: 800px)')
return (
<Container className={Styles.loginContainer}>
<Header className={Styles.loginHeader} showButtons={false} />
<LoginForm />
{
!isMobile && <Footer />
}
</Container>
);
}
14.使用lodash来判断数据是否存在(避免一些报错异常)
代码语言:javascript复制import _ from 'lodash'
const ProductItem = (props: any) => {
const { product, onRequest } = props
return (
<div className={Styles.similarPrdItem}>
{!_.isEmpty(product.images) && (
<YourCom/>
)
}