React-AntD常见问题

目录

 

一、antd getFieldDecorator使用rules不起作用

(一)问题描述

(二)解决问题

二、监听页面宽度动态

1.在componentDidMount()中加入监听器

2.在constructor中绑定resize()

3.在componentWillUnmount()中移除监听器

三、联动下拉框清空问题

四、一个页面调用的多个相同组件,导致props相互影响的问题

五、可伸缩列的表格


一、antd getFieldDecorator使用rules不起作用

(一)问题描述

使用getFieldDecorator的rules规则限制,只提示而不终止函数给出相应的提示。

例如,在一个modal弹窗中,一个输入框不符合rules规则时候会提出相应的提示,但是,点击‘保存’或者‘确定’的时候仍然能执行后台api且关闭。

(二)解决问题

原因:缺少validateFields()验证。

解决如下:

无法完场终止函数验证是因为缺少下面这段代码,加上即可。

this.props.form.validateFields((err, vals) => {
    if (!err) {
    }
})

二、监听页面宽度动态

1.在componentDidMount()中加入监听器

componentDidMount() {
    this.screenChange();
}

screenChange() {
    window.addEventListener('resize', this.resize);
}

resize()方法中,定义了屏幕尺寸变化后需要执行的代码,可定义一个state,在resize中赋值

 

2.在constructor中绑定resize()

constructor(props) {
    this.resize.bind(this);
}

 

3.在componentWillUnmount()中移除监听器

componentWillUnmount() {
    window.removeEventListener('resize',this.resize);
}

注:一定要移除监听器,否则多个组件之间会导致this的指向紊乱!!!

 


三、联动下拉框清空问题

上级改变,下级清空,select写在表单里,用了getFieldDecorator)

解决这个问题,不能用state传值,select是写在表单里的,用了getFieldDecorator所以浏览器就华丽的报错了,报错内容:

Warning: `getFieldDecorator` will override `value`, so please don't set `value` directly and use `setFieldsValue` to set it.

也不能使用initialValue,但是initialValue是设置初始值,只render执行一次就不执行了,需要使用setFieldsValue方法。注意:antd中form表单的setFieldsValue只能设置其他域的值,不能控制自己表单域的值。

想要setFieldsValue设置自己值使输入框受控,想把redux中传过来的props绑定到form,使props改变表单值实时改变,使用options.normalize

官方解释:转换默认的 value 给控件;function(value, prevValue, allValues): any

const { getFieldProps } = this.props.form;
return (
    <div>
        <Select
        {...getFieldProps('name', {
            normalize: (value, prevValue, allValues) => {
                let targetValues = []
                const nowValues = prevValue || [];
                if (nowValues.length > value.length) {
                targetValues = value;
                } else {
                    const selectValue = value.find(nv => nowValues.indexOf(nv) === -1)
                    if (selectValue === '0') {
                        targetValues = ['0']
                    } else {
                        targetValues = value.filter(x => x !== '0');
                    }
                }
                return targetValues;
            }
        })}
        style={{ width: 800 }}
        mode="multiple"
        >
            {data.map((item) => <Option key={item.value}>{item.name}</Option>)}
        </Select>
    </div>
);

以上是 normalize 的代码,通过转换返回新的值,不会出现两次渲染。

 

要实现联级下拉框清空,使用如下:

//效果:第一行改变,会置空其后组件的值 和 第二行组件的值
{getFieldDecorator(fieldName, {
    rules: fieldConfig.rules || [{ required: false, message: '' }],
    initialValue: initialValue[fieldName],
    normalize:(value, prevValue) => {
    //index是行序数(从0开始),length是一行内的组件数,
    //i是此行内的组件序数(从0开始),count为此时的组件坐标位置
    //如果不限制为第一行的话,const count = i + length * index;不再适用
    const count = i + length * index;
    if (value !== prevValue && index < 1) {
        //触发变值时记录位置,赋给全局变量countValue,只记录第一行
        countValue = count;
    } else if (countValue < count && index < 2) {
        //触发变值的组件在该组件的位置前,置空其后组件的值,不置空第三行
        return '';
    }
     return value;
    }
}

但在一些复杂特殊的情况下,依然不能实现相关需求,建议使用相关变量作为React组件的key值,强制两次渲染。

 


四、一个页面调用的多个相同组件,导致props相互影响的问题

不能要复用的组件获取数据也连到redux里面的,不可能通过dispatch来发出消息,会相互影响的。

解决方法一:直接在组件内部发请求,而不是通过redux或者dvajs,里面的数据都是直接在组件里面直接fetch的,然后用state保存。

举例如下:

export async function getCount(params) {
    return request(url, params);
}

export default class ShowCount extends React.Component {
    constructor() {
        super();
        this.state = {
            loading: true,
            count: 0,
        };
    }

    @Bind
    loadCount() {
        const { params } = this.props;
        let count = 0;
        try {
            count = await getTunnelCountByRegion(region);
            sessionStorage.setItem(region, count);
        } catch (err) {
            message.error(`fail to query count`);
        }
        this.setState({
            loading: false,
            count,
        });
    }

    componentDidMount() {
        this.loadCount();
    }


    render() {
        return this.state.loading ? 
            <Icon style={{ paddingLeft: 12 }} type="loading" />
            : (this.state.count);
    }
}

五、可伸缩列的表格

需要我们把react-resizable中的styles.css引入或者复制到当前app.css中才能使用

import '../node_modules/react-resizable/css/styles.cs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值