Will Black
Will Black

Reputation: 402

fill antd form fields with props

I got simple blog (react/redux) (only frontend part). With user registration and articles. And stuck when tryed to fill fields of article editor form.

In "ArticleEditor" component. When I try edit article I got all values in props, and can see it in console log

console.log('title:', this.props.title); // title 

but how to add it to form fields? In form fields values i got -

value={this.props.title}

but fields its empty. Should i need to somehow update this form? Is't it update when it recieve props?

Plz help if you have good knowledge in React/Redux.

here is the code: https://codesandbox.io/s/blissful-chatterjee-e82j6

Upvotes: 0

Views: 3712

Answers (3)

Dipen Shah
Dipen Shah

Reputation: 26075

So the solution to your problem is two fold.

  1. Replace use of value with initialValues for the form
  2. Do not show form until values are loaded from the server. When re-rendering happens after state change, original form components are not stored and they are still holding onto first value bound.
import React from "react";
import ErrorsList from "../ErrorsList/ErrorsList";
import userService from "../../services/userService";
import { connect } from "react-redux";
import { push } from "react-router-redux";
import { useParams } from "react-router-dom";
import { Form, Input, Button } from "antd";

import { ADD_TAG, REMOVE_TAG } from "../../actionTypes";

import { store } from "../../store";
import actionCreators from "../../actionCreators";
import article from "../../reducers/article";

const formItemLayout = {
  labelCol: { span: 24 },
  wrapperCol: { span: 24 }
};

const formSingleItemLayout = {
  wrapperCol: { span: 24, offset: 0 }
};

const mapStateToProps = (state) => ({
  ...state.editor
});

const mapDispatchToProps = (dispatch) => ({
  onLoad: (payload) => dispatch(actionCreators.doEditorLoaded(payload)),
  onUnload: () => dispatch(actionCreators.doEditorUnloaded()),
  onUpdateField: (key, value) =>
    dispatch(actionCreators.doUpdateFieldEditor(key, value)),
  onSubmit: (payload, slug) => {
    dispatch(actionCreators.doArticleSubmitted(payload));
    store.dispatch(push(`/`)); //article/${slug}
  },
  onRedirect: () => dispatch(actionCreators.doRedirect())
});

class ArticleEditor extends React.Component {
  constructor(props) {
    super(props);
    this.id = this.props.match.params.id;
    const updateFieldEvent = (key) => (e) =>
      this.props.onUpdateField(key, e.target.value);
    this.changeTitle = updateFieldEvent("title");
    this.changeDescription = updateFieldEvent("description");
    this.changeBody = updateFieldEvent("body");
    this.changeTagInput = updateFieldEvent("tagInput");
    this.isLoading = true;

    this.submitForm = () => {
      const article = {
        title: this.props.title,
        description: this.props.description,
        body: this.props.body,
        tagList: this.props.tagInput.split(",")
      };

      const slug = { slug: this.props.articleSlug };
      const promise = this.props.articleSlug
        ? userService.articles.update(Object.assign(article, slug))
        : userService.articles.create(article);

      this.props.onSubmit(promise, this.props.articleSlug);
    };
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("id", prevProps.match.params.id);
    if (prevProps.match.params.id !== prevProps.match.params.id) {
      if (prevProps.match.params.id) {
        this.props.onUnload();
        return this.props.onLoad(
          userService.articles.get(this.props.match.params.id)
        );
      }
      this.props.onLoad(null);
    }
    this.isLoading = false;
  }

  componentDidMount() {
    if (this.id) {
      this.isLoading = true;
      return this.props.onLoad(userService.articles.get(this.id));
    }
    this.isLoading = false;
    this.props.onLoad(null);
  }

  componentWillUnmount() {
    this.props.onUnload();
  }

  render() {
    const { errors } = this.props;
    const initialValues = {
      title: this.props?.title,
      body: this.props?.body,
      description: this.props?.description,
      tags: this.props?.tagList
    };

    return this.isLoading ? (
      "loading..."
    ) : (
      <div className="editor-page">
        <div className="container page">
          <div className="">
            <div className="">
              <ErrorsList errors={errors}></ErrorsList>
              <Form
                {...formItemLayout}
                initialValues={initialValues}
                onFinish={this.submitForm}
              >
                <Form.Item
                  label="Title"
                  name="title"
                  placeholder="Article Title"
                  rules={[
                    {
                      required: true,
                      message: "Please input article title"
                    }
                  ]}
                >
                  <Input onChange={this.changeTitle} />
                </Form.Item>
                <Form.Item
                  label="Description"
                  name="description"
                  placeholder="Short description"
                  rules={[
                    {
                      required: true,
                      message: "Please input article description"
                    }
                  ]}
                >
                  <Input onChange={this.changeDescription} />
                </Form.Item>
                <Form.Item
                  name="body"
                  label="Article Text"
                  placeholder="article text"
                >
                  <Input.TextArea onChange={this.changeBody} />
                </Form.Item>
                <Form.Item name="tags" label="Tags" placeholder="Enter tags">
                  <Input onChange={this.changeTagInput} />
                </Form.Item>
                <Form.Item {...formSingleItemLayout}>
                  <Button
                    className="editor-form__btn"
                    type="primary"
                    htmlType="submit"
                    disabled={this.props.inProgress}
                  >
                    Submit Article
                  </Button>
                </Form.Item>
              </Form>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(ArticleEditor);

take a look at this codesandbox.

Upvotes: 1

Chandan
Chandan

Reputation: 11797

I just checked that you are using v4 not v3

you can use fields props in Form Component

<Form
   {...formItemLayout}
   onFinish={this.submitForm}
   fields={[
     {
       name: ['title'],
       value: title,
     },
   ]}
>

Upvotes: 2

Chandan
Chandan

Reputation: 11797

Add defalutValue prop in Input with value eg:

<Input.TextArea value={body} defaultValue={body} onChange={this.changeBody} />

Upvotes: 0

Related Questions