Redux Form - redux表单中组件的初始值

时间:2017-08-31 12:28:34

标签: javascript reactjs redux redux-form

新手。

我有一个名为Client的redux表单组件。该表单中有一个名为Address的子组件。在客户端中调用Address,如下所示:

      <FormSection name="Address">
        <Address />
      </FormSection>

Address的格式为AddressContainerAddress

我正在为Client redux表单设置初始值,如下所示:

  let ClientForm = reduxForm({
    form: CLIENT_FORM_NAME
  })(Client);

  let ClientForm2 = connect(
    (state, ownProps) => ({
      initialValues: ownProps.isEditMode ? state.editClient : {}, // pull initial values from client reducer
      enableReinitialize: true
    }),
    { reducer } // bind client loading action creator
  )(ClientForm);

  export default ClientForm2;

但是Address组件没有设置任何初始状态。

你如何以redux形式将初始状态从主窗体传递到其子组件 - 在这种情况下是Address

AddressContainer:

  import React, { Component, PropTypes } from "react";
  import { connect } from "react-redux";
  import { Field, change } from "redux-form";
  import { Col, Panel, Row } from "react-bootstrap";
  import Select from "react-select";

  import Address from "./address";
  import { getSuburbs, ensureStateData } from "./actions";

  import FormField from "../formComponents/formField";
  import TextField from "../formComponents/textField";
  import StaticText from "../formComponents/staticText";

  import { CLIENT_FORM_NAME } from "../clients/client/client";

  export class AddressContainer extends Component {
    static contextTypes = {
      _reduxForm: PropTypes.object.isRequired
    };

    constructor(props, context) {
      super(props, context);

      this.state = {
        selectedSuburb: null
      };
    }

    // Manage Select.Async for new data request - for suburbs.
    handleSuburbSearch = query => {
      const { addressData } = this.props;
      const companyStateId = addressData.companyStateId;

      if (!query || query.trim().length < 2) {
        return Promise.resolve({ options: [] });
      }
      const queryString = {
        query: query,
        companyStateId: companyStateId
      };
      return getSuburbs(queryString).then(data => {
        return { options: data };
      });
    };

    // Update the current state with the selected suburb.
    onSuburbStateChange = value => {
      this.setState({ selectedSuburb: value });
    };

    componentDidMount() {
      this.props.ensureStateData();
    }

    render() {
      const { initialValues, addressData, updatePostcodeValue } = this.props;

      const { value } = this.state;
      const sectionPrefix = this.context._reduxForm.sectionPrefix;

      if (addressData.isLoading || !addressData.states.length) {
        return <p>Loading</p>;
      }
      if (addressData.error) {
        return <p>Error loading data</p>;
      }

      console.group("InitalValues Address");
      const companyStateId = addressData.companyStateId;
      console.log("companyStateId:", companyStateId);
      initialValues.Address = {
        ...initialValues.Address,
        state: addressData.states.find(
          option => option.stateId === companyStateId
        )
      };
      console.log(
        "addressData.states.Find: ",
        addressData.states.find(option => option.stateId === companyStateId)
      );
      console.log("addressData.states: ", initialValues.Address.state);
      console.log("initialValues.Address: ", initialValues.Address);
      console.log("initialValues: ", initialValues);
      console.groupEnd();

      return (
        <Address
          initialValues={initialValues}
          handleSuburbSearch={this.handleSuburbSearch}
          onSuburbStateChange={this.onSuburbStateChange}
          updatePostcodeValue={updatePostcodeValue}
          addressData={addressData}
          sectionPrefix={sectionPrefix}
        />
      );
    }
  }

  const mapStateToProps = state => ({
    initialValues: state.editClient,
    companyStateId: state.companyStateId,
    addressData: state.addressData
  });

  const mapDispatchToProps = dispatch => ({
    ensureStateData: () => dispatch(ensureStateData()),
    getSuburbs: values => dispatch(getSuburbs(values)),
    updatePostcodeValue: (postcode, sectionPrefix) =>
      dispatch(
        change(
          CLIENT_FORM_NAME,
          `${sectionPrefix ? sectionPrefix + "." : ""}postcode`,
          postcode
        )
      )
  });
  export default connect(mapStateToProps, mapDispatchToProps)(AddressContainer);

地址:

  import React, { Component, PropTypes } from "react";
  import { connect } from "react-redux";
  import { Field, change, reduxForm } from "redux-form";
  import { Col, Panel, Row } from "react-bootstrap";
  import Select from "react-select";
  import { getSuburbs } from "./actions";
  import FormField from "../formComponents/formField";
  import TextField from "../formComponents/textField";
  import StaticText from "../formComponents/staticText";

  import reducer from "../address/reducer";

  export const Address = props => {
    const {
      initialValues,
      handleSuburbSearch,
      companyValue,
      onSuburbStateChange,
      updatePostcodeValue,
      addressData,
      sectionPrefix
    } = props;

    const { reset } = props;

    {
      console.log("PROPS ADDRESS DATA: ", props.stateData);

      console.log("PROPS INITIALVALIES: ", props.initialValues);

      console.log("COMPANY VALUE: ", companyValue);
    }

    return (
      <Panel header={<h3>Client - Address Details</h3>}>
        <Row>
          <Field
            component={TextField}
            name="address1"
            id="address1"
            type="text"
            label="Address Line 1"
            placeholder="Enter street 1st line..."
            fieldCols={6}
            labelCols={3}
            controlCols={9}
          />
          <Field
            component={TextField}
            name="address2"
            id="address2"
            type="text"
            label="Address Line 2"
            placeholder="Enter street 2nd line..."
            fieldCols={6}
            labelCols={3}
            controlCols={9}
          />
        </Row>
        <Row>
          <Field
            component={props => {
              const { input, id, placeholder, type } = props;
              const {
                fieldCols,
                labelCols,
                controlCols,
                label,
                inputClass
              } = props;

              // The props we want the inner Select textbox to have.
              const { name, onChange } = input;
              const onStateChange = state => {
                console.log("onStateChange", state);
                onChange(state);
              };

              return (
                <FormField
                  id={id}
                  label={label}
                  fieldCols={fieldCols}
                  labelCols={labelCols}
                  controlCols={controlCols}
                  inputClass={inputClass}
                >
                  <Select
                    name={name}
                    onChange={onStateChange}
                    placeholder="Select state"
                    valueKey="id"
                    options={addressData.states}
                    labelKey="stateLabel"
                    optionRenderer={option =>
                      `${option.stateShortName} (${option.stateName})`}
                    value={input.value}
                    selectValue={
                      Array.isArray(input.value) ? input.value : undefined
                    }
                  />
                </FormField>
              );
            }}
            name="state"
            id="state"
            label="State."
            fieldCols={6}
            labelCols={3}
            controlCols={6}
          />
        </Row>
        <Row>
          <Field
            component={props => {
              const { input, id, placeholder, type } = props;
              const {
                fieldCols,
                labelCols,
                controlCols,
                label,
                inputClass
              } = props;

              // The props we want the inner Select.Async textbox to have.
              const { name, value, onChange, onBlur, onFocus } = input;

              // A suburb was selected so "onChange" is updated along
              //with the static form component "Postcode".
              const onSuburbChange = value => {
                onSuburbStateChange(value);
                input.onChange(value);
                updatePostcodeValue(value ? value.postcode : null, sectionPrefix);
              };

              return (
                <FormField
                  id={id}
                  label={label}
                  fieldCols={fieldCols}
                  labelCols={labelCols}
                  controlCols={controlCols}
                  inputClass={inputClass}
                >
                  <Select.Async
                    {...input}
                    onChange={onSuburbChange}
                    placeholder="Select suburb"
                    valueKey="id"
                    labelKey="suburbName"
                    value={input.value}
                    loadOptions={handleSuburbSearch}
                    backspaceRemoves={true}
                  />
                </FormField>
              );
            }}
            name="suburb"
            id="suburb"
            label="Suburb."
            fieldCols={6}
            labelCols={3}
            controlCols={9}
          />
        </Row>
        <Row>
          <Field
            component={StaticText}
            name="postcode"
            id="postcode"
            label="Postcode."
            fieldCols={6}
            labelCols={3}
            controlCols={9}
          />
        </Row>
      </Panel>
    );
  };
  Address.propTypes = {
    handleSuburbSearch: PropTypes.func.isRequired,
    onSuburbStateChange: PropTypes.func.isRequired
  };

  const AddressForm = reduxForm({
    form: "Address"
  })(Address);

  let AddressForm2 = connect(
    (state, ownProps) => ({
      initialValues: state.editClient, // pull initial values from client reducer
      enableReinitialize: true
    }),
    { reducer } // bind client loading action creator
  )(AddressForm);

  export default Address;
来自Chrome中Redux工具的

state.editClient:

请注意,address1suburbpostcode都有值及其在Address组件中未显示的值...

enter image description here

0 个答案:

没有答案