0
export class ProjectList extends Component{
    constructor(props){
        super(props)
        this.state={
            project:[],
        }
    }
    componentDidMount(){
        axios.get('http://127.0.0.1:9090/pro/pList').then(res =>{
            this.setState({
                project:res.data.page.datas
            })
        })
    }
    render(){
        return (
                    <Select key='project' style={{width:"100%"}}  placeholder="请选择项目">
                        {
                            this.state.project.map((item,i) =>{
                                return(
                                    <Option key={`project${i}`} value={item.id}>{item.name}</Option>
                                )
                            })
                        }
                    </Select>
        )
    }
}
class AddOrderType extends Component{
    render(){
        
        return(
            <Modal
            title="调整角色"
            wrapClassName="vertical-center-modal"
            visible={this.props.ishow}
            onOk={this.handleOk}
            onCancel={this.handleCancel}
            footer={[
                <Button key="back" size="large" onClick={this.handleCancel}>取消</Button>,
                <Button key="submit" type="primary" size="large" loading={loading} onClick={this.handleOk}>
                  提交
                </Button>,
              ]}
            >
            <FormItem
                {...formItemLayout}
                label="所属项目"
                >
                {getFieldDecorator('project',{
                    rules: [{
                        required: true, 
                        message: '所属项目!'
                    }],
                })(<ProjectList values={this.state.values} onChange={this.onChange} />)}//这里就是上面声明的组件
            </FormItem>
            </Modal>
        )
    }
}

现在是个弹出框在弹出框里包含了一个这样的select 因为很多地方都要用到这个select 所以我把select又封装了一下。现在弹出框正常 select组件也正常,但是当用户操作了一下select之后关闭弹出框,再次打开,这个select的值就是上次操作的值,并没有被重置掉。如果用value赋值,会导致select变成无法操作的状态.如果用defaultValue的话只能在第一次加载时有效。

**

不要只说一些理论上的东西,比如通过props重置之类的含糊不清的回答,请在实践后作出合理的回答。

**

3个回答

0

这算不上封装。
Select组件变为受控组件就可以了。

<Select value={this.props.value} onChange={v => this.props.onChange(v)}></Select>
0

在antd的表单组件里面使用value是无效的,初始化数据使用initialValue,重置数据使用resetFields,具体使用自己看api

0

我之前也和你遇到了一样的困扰,react在遇到双标签组件时候,如果只改变它的child,由于组件自己的props和state没有发生变化,根据diff的算法是不会继续遍历其子组件,于是react就认为这个组件是一样的。

目前我想到的一个解决办法是使用shouldComponentUpdate方法加上把选项的value作为一个属性,通过检查传入的对象是否发生了改变,来重置this.value,达到强制清空的效果。

class mySelect extends React.Component {
    constructor(...args) {
        super(...args);
        this.value = [];
    }
    ...
    shouldComponentUpdate(newprops) {
        const { options } = newprops, oldOpts = this.props.options;
        if ( options.length != oldOpts.length ) {
            this.value = [];    
        } else {
            for ( let opt of options ) {
                if ( !oldOpts.includes(opt) ) {
                    this.value = [];
                    break;
                }
            }
        }
        return true;
    }
    ...
    render() {
        const { options } = this.props;
        const option = options.map( val => <Option key = { val }>{ val }</Option> );
        const select = (
            <Select value = { this.value }>{ option }</Select>
        );
        return (
            <>
                <myTag>
                    some anthor tags...
                </myTag>
                { select }
            </>
        );
    }
}

这个方法有个弊端,你需要确保每次做任何操作(包括选择)是组件都要重新渲染(需要有调用setState方法或者props的更新),目前还没想到办法解决这个问题。

其实这个方法并不是一个最好的方法,这不符合react的编程思想,一般这种情况是由于你没有把state统一管理,让组件的state分散在各个层级,所以我建议你最好先理解react的状态提升,让最高层级的组件去管理它的子组件,通过props的形式传递state。

以这个问题为例子,其实你应该在最上层的组件设置好一个value的state,然后以props的形式传入Select组件,那样Select组件便能通过this.props.value知道自己现在选择的选项,当你的选项数据发生了变化的时候,在最上层的组件setState({ value: [] }),这样Select便会清空。

撰写答案

Planets