美文网首页
记录react

记录react

作者: 不行了快拦住我 | 来源:发表于2021-11-18 10:09 被阅读0次

    一、框架使用

    antd pro component - EditableProTable 表单重置

    受控情况之下,改变 dataSource之后,但是表格编辑组件还是记录上次编辑状态记录的数据,没有及时更新,解决办法就是手动更新表单(其实整个表格就是一个form)

      // 声明form实例
      const [form] = Form.useForm();
      console.log('打印formValues:',form.getFieldsValue());
    
     <EditableProTable<OrderCargoDtoType>
                // scroll={{ x: 1300 }}
                rowKey="id"
                columns={columnsArr(short_width, options, onSelect, onSearch)}
                // request={requestTableData}
                dataSource={dataSource}
                pagination={pageConfig}
                actionRef={tableRef}
                //onChange={setDataSource}
                rowSelection={{ ...rowSelection, checkStrictly: false }}
                toolBarRender={() => {
                  return renderTableToolBar(save, handleExport, dataCensus, batch,openEdit);
                }}
                editable={{
                  form:form,
                  type: 'multiple',
                  .....
    
    
    
    //这里是修改dataSource的地方,也是需要更新表单的地方
    
    
     getData={(data: any) => {
                  modifyRowKeys.forEach((ele, index) => {
                    let i = dataSource.findIndex((item) => {
                      return item.id == ele;
                    });
    
                    for (let key in data) {
                       dataSource[i][key] = data[key];
                     }
                  });
                   setDataSource(dataSource);
                   //------------------就是这里!!!--------------
                  form.resetFields();
                 }}
    

    二、dva使用

    新建js文件 为dva仓库
    设置名称 namespace: 'company',
    设置state: {
        enumeration: '', // 获取所有枚举
        options: optinons,
        default: 0,
        isExist: false,
        user: '', //用户信息
      },
    effects内部为异步函数 不可修改state 需要put提交到reducers修改
    *为省略写法的箭头函数
    函数接收两个参数 {state},{ put, call}
    state为仓库数据,put为提交到同步方法,内部为type函数名称,payload为提交参数
    reducers内部为同步方法,唯一修改state数据方法,需要disptch提交,两个参数,type:’company/changeCompany‘,type写法为仓库名/函数名,payload为提交参数
    
    const CompanySelet = {
      namespace: 'company',
      state: {
        enumeration: '', // 获取所有枚举
        options: optinons,
        default: 0,
        isExist: false,
        user: '', //用户信息
      },
      effects:{
        *getUser({state},{ put, call}){
          const { data = {}}=  yield call(getEmployeeWithCurrentUser);
          yield put({
            type:'setUser',payload:data
          });
        },
        *getEnu({state},{ put, call}){
          const { data = {}}=  yield call(getEnums, params.join(','));
          const res = {...data, ...list}
          let obj = {}
          let arr = []
          for (const item of paramsMap) {
            if(res[item]) {
              arr = Object.keys(res[item]).map(key => {
                return { code: res[item][key], desc: key }
              })
              obj[item] = arr
            }
          }
          yield put({
            type:'setEnu',payload:obj
          });
        }
      },
      reducers: {
        changeCompany(state, action) {
          //固定写法 return 返回整体state
          return {
            ...state,
            isExist: action.payload || false,
          };
        },
      },
    };
    
    export default CompanySelet;
    
    
    组件内使用
    import { connect } from 'dva';
    const 组件名 = (props) => {
    this.props.dispatch({
            type: 'company/getEnu',
            payload:{a:1}
          })
    }
    export default connect(({ company }) => ({  company}))(组件名);
    
    // 重点: 首次进入网站,无法触发effect方法,需要在effect中使用try{}catch{}方法
    

    三、antd pro proLayOut 菜单分割时

    image.png

    定义三级路由,使一级路由自动匹配到三级路由,必须在三级路由最后面加上一级路由的path和重定向,如果设置component,为显示当前一级路由页面

    四、antd pro proLayOut 菜单分割时

    [React中setState如何同步更新 ]

    同步更新策略

    1.完成回调

    setState函数的第二个参数允许传入回调函数,在状态更新完毕后进行调用,譬如:

    [ 复制代码

    ](javascript:void(0); "复制代码")

    this.setState({
          load: !this.state.load,
          count: this.state.count + 1 }, () => {
          console.log(this.state.count);
          console.log('加载完成')
        });
    
    [ 复制代码

    ](javascript:void(0); "复制代码")

    2.Promise封装结合async/await

    其实这里就是JavaScript异步编程相关知识,将上面回调写法换成Promise

    引入Promise来封装setState:

    setStateAsync(state) { return new Promise((resolve) => { this.setState(state, resolve)
        });
      }
    
    
    setStateAsync 返回的是Promise对象,在调用时我们可以使用Async/Await语法来优化代码风格:
    
    [![复制代码](https://img.haomeiwen.com/i2772613/5911975d5e684256.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
     async componentDidMount() {
    
           await this.setStateAsync ({
    
                   count: this.state.count * 1 + 2
    
               })
    
               console.log(123, this.state.count)
    
               await this.setStateAsync ({
    
                   count: this.state.count * 1 + 2
    
               })
    
               console.log(456, this.state.count)
    
    [![复制代码](https://img.haomeiwen.com/i2772613/78af9cf7ed38c157.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    

    3.直接使用操作异步函数async / await

    此时每次await setState都会执行一遍render方法
    
    [![复制代码](https://img.haomeiwen.com/i2772613/66324513e63c57a4.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
    handleChange = async () => {
    
               await this.setState({
    
                   count: this.state.count * 1 + 2
    
               })
    
               console.log(123, this.state.count)
    
               await this.setState({
    
                   count: this.state.count * 1 + 2
    
               })
    
               console.log(456, this.state.count)
    
    }
    
    [![复制代码](https://img.haomeiwen.com/i2772613/2c650c96164ae596.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    

    四、setState参数详解

    state中定义count初始值为1;

    1.第一个参数为传入对象;

    [![复制代码](https://img.haomeiwen.com/i2772613/d75d1b488a117435.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
    handleChange = () => { this.setState({
                count: this.state.count  + 2 })
            console.log(123, this.state.count) this.setState({
                count: this.state.count  + 2 })
            console.log(456, this.state.count)
        }
    
    [![复制代码](https://img.haomeiwen.com/i2772613/1d4e7d1275a984ae.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
    调用方法两次输出值为都为3;
    

    React 出于性能方面的考虑,并不会直接对每次的调用都进行更新,而是会将多次传入的对象进行合并处理,以产生一个新的最终的 state 对象;

    第二个参数为完成回调

    [![复制代码](https://img.haomeiwen.com/i2772613/a1150a09da60229a.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
    handleChange = () => { this.setState({
                count: this.state.count  + 2 }, () => {
                console.log(123, this.state.count)
            }) this.setState({
                count: this.state.count  + 2 }, () => {
                console.log(456, this.state.count)
            })
        }
    
    
    [![复制代码](https://img.haomeiwen.com/i2772613/948777de8dd3fae9.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    
    与上面输出保持一致
    

    2.第一个参数为传入函数:

    [![复制代码](https://img.haomeiwen.com/i2772613/132169dc10cd60d4.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    handleChange = () => { this.setState((prevState, props) => ({
                count: prevState.count + 2 }), () => {
                console.log(123, this.state.count)
            }) this.setState((prevState, props) => ({
                count: prevState.count + 2 }), () => {
                console.log(456, this.state.count)
            })
        }
    
    [![复制代码](https://img.haomeiwen.com/i2772613/f087fcf2b5600d80.gif?imageMogr2/auto-orient/strip)](javascript:void(0); "复制代码") 
    

    函数第一个参数接收先前的状态作为第一个参数,将此次更新被应用时的props做为第二个参数;

    此时输出为两次都是5;

    在第二次调用 setState 方法时便可以通过 prevState.count 拿到最新的值从而更新本次的 state 。显然,React 对于传入函数的方式和传入对象的方式进行更新 state 的各自具体理念是不一样的,对于传入函数的方式,在调用 setState 进行更新 state 时,React 会按照各个 setState 的调用顺序,将它们依次放入一个队列,然后,在进行状态更新时,则按照队列中的先后顺序依次调用,并将上一个调用结束时产生的 state 传入到下一个调用的函数中,当然,第一个 setState 调用时,传入的 prevState 则是当前的 state ,如此,便解决了传入对象式调用 setState 方法所存在的 不能依赖上一次的 state 去计算本次 state 的问题。

    [ 复制代码

    ](javascript:void(0); "复制代码")

    <pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;">handleChange = () => { this.setState((prevState, props) => ({
    count: prevState.count + 2 }), () => {
    console.log(123, this.state.count)
    }) this.setState((prevState, props) => ({
    count: this.state.count + 2 }), () => {
    console.log(456, this.state.count)
    })
    }</pre>

    [ 复制代码

    ](javascript:void(0); "复制代码")

    值得一提的是,在上面的这段代码中,执行第二个 setState 里面的函数时,由第一个 setState 所产生的最新的 state 并没有合并到 this 对象上面去,所以此时通过 this.state 获取不到最新的状态,故而在函数内部拿到的 this.state.count 的值为 1 而非 3。

    另外,不论第一个参数是何种类型,多次setState也只会调用一次render方法,第二个参数callback完成回调中获取this.state的值同样也是多次setState合并操作后的最终值;

    相关文章

      网友评论

          本文标题:记录react

          本文链接:https://www.haomeiwen.com/subject/bgjdtrtx.html