前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >react hook+ts+rouerV6 dev notes

react hook+ts+rouerV6 dev notes

作者头像
biaoblog.cn 个人博客
发布2022-08-11 19:36:26
2.4K0
发布2022-08-11 19:36:26
举报
文章被收录于专栏:web技术开发分享

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/>
  )
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.React useHistory 更新为useNavigate如何传值
  • 2.封装公共dialog的小技巧(children props使用)
  • 3.使用antd-form的内嵌组件(包括验证)
  • 4.重置antd-form
  • 5.hook的useEffect 实现class的componentWillReceiveProps
  • 6.antd的上传组件 实现自定义上传(类似于element的自定义上传文件)
    • 首先是elementUI的自定义上传代码(关注:http-request):
      • 组件部分:
        • 然后是antd的自定义上传设置
          • 首先是组件:(关注customRequest部分)
          • 7.antd-form中自动获取checkbox组件的值
          • 8.react-redux 持久化 仓库配置(包含thunk)
          • 9.在react-hook中获取到redux仓库中的值(封装了thunk)
          • 10.一个Input的动态样式,可以参考
            • unclick:
              • click:
              • 11.antd-form 自定义校验
              • 12.一个href的动画css效果
              • 13.使用useMediaQuery来判断pc和mobile
              • 14.使用lodash来判断数据是否存在(避免一些报错异常)
              相关产品与服务
              验证码
              腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档