Selvin
Selvin

Reputation: 815

Ant Design form set values form props

I'm using antd design in my form.

Here I'm setting value from reducer profilereducer by using shouldComponentUpdate method.

class ProfileForm extends Component {

 componentDidMount = () => {
  this.props.actions.getprofile()
 }

 shouldComponentUpdate = (nextProps) => {
  if (this.props.profile) {
   this.props.form.setFieldsValue({
    name: this.props.profile.name,
   });
  } else {
   this.props.form.setFieldsValue({
    firstname: 'loading',
   });
  }
 }


 render() {
  const { getFieldDecorator, getFieldValue } = this.props.form; 
     <Form layout="vertical">
        <FormItem label="First Name" >
            {getFieldDecorator('name', { rules: [{ required: true, message: 'Required!', }], })(
                <Input addonBefore={selectBefore} placeholder="First Name" />
            )}
        </FormItem>
    </Form>    
}


 function mapStateToProps(state) {
  return {
   profile: state.profilereducer.profile,
  }
 }

 function mapDispatchToProps(dispatch) {
  return {
   actions: bindActionCreators(actions, dispatch)
  }
 }

 const Profile = Form.create()(ProfileForm);

 export default connect(mapStateToProps, mapDispatchToProps)(Profile);
}

Error:

enter image description here

Upvotes: 7

Views: 24734

Answers (2)

Hemanthvrm
Hemanthvrm

Reputation: 2457

You are setting state in a loop, hence you got the error. Here is a better approach of dealing it.. I just left selectBefore as a variable(in your code, i haven't found setting it).. Change it to string if you get error..

componentDidMount = () => {
   this.props.actions.getprofile()
  }

  renderBasicform(initialVal) {
    const { getFieldDecorator, getFieldValue } = this.props.form;
    return (
      <Form layout="vertical">
        <FormItem label="First Name" >
          {getFieldDecorator('name', { initialValue: initialVal,rules: [{ required: true, message: 'Required!', }], })(
            <Input addonBefore={selectBefore} placeholder="First Name" />
          )}
        </FormItem>
      </Form>
    );
  }

  render() {
    if(!this.props.profile) {
        return (
          <div>
          {this.renderBasicform("Loading")}
          </div>
        );
    }

        return (
          <div>
            {this.renderBasicform(this.props.profile.name)}
            </div>
        );
  }

Upvotes: 5

hakeri
hakeri

Reputation: 196

As the function name hints at, the shouldComponentUpdate should return a boolean. Either it should return true if render() should be called (which is normally the default), or false if not. It is mainly intended as an optimization function, where the developer can skip re-rendering the component in certain circumstances. See the react documentation for example the function: https://reactjs.org/docs/react-component.html#shouldcomponentupdate

Secondly, I am note sure why you even want to do a remapping between profile and form. It is generally considered an anti-pattern to mutate or change properties directly inside the component classes like this. Is there a particular reason why you are trying to remap the profile data to the form property? Would it not be simpler to either construct that mapping the render function and pass it to the <Form> there? Or better yet, have the reducer map this data as you would like to have it from the start, without having to properties with similar data but different structure.

Upvotes: 0

Related Questions