更新reactjs状态的更简洁方法

时间:2017-07-12 02:17:39

标签: javascript reactjs redux

我的应用程序的用例是。应从服务器获取数据并以表单形式显示这些数据,以便用户可以使用预加载的数据更新表单。表格应该控制一个而不是不受控制。对于这个用例,我所做的是从componentDidMount生命周期内的服务器获取数据,这是首选的。在componentWillReceiveProps中,我检查了是否有数据,如果有,则更新本地反应状态与来自服务器的数据。现在我在react本地状态中有数据,然后我开发了一个表单并使用onChange事件处理程序在value属性中填充这些数据。这是有效的,但我正处于学习阶段我需要从专家那里了解如果你必须如何处理这样的用例。任何人都可以帮我编写更好的代码吗?我在代码审查中没有看到巨大的反应社区。如果我需要关闭这个问题,我会请,但请善待。我估计,学习不应该有任何障碍。这是我的观点。

const mapDispatchToProps = dispatch => ({
  requestCloudinary: cloudinary => dispatch(cloudinaryRequest(cloudinary)),
  loadCloudinary: () => dispatch(fetchCloudinary())
});

const mapStateToProps = createStructuredSelector({
  cloudinaryService: selectCloudinary()
});

class Cloudinary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cloudinary: {
        _id: "",
        cloudinary_cloud_name: "",
        cloudinary_api_key: "",
        cloudinary_api_secret: ""
      },
      errors: {}
    };
  }

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

  componentWillReceiveProps(nextProps, prevProps) {
    const { cloudinaryService } = nextProps;
    if (cloudinaryService.size) {
      cloudinaryService
        .entrySeq()
        .map(([key, value]) => {
          this.setState(state => ({
            cloudinary: { ...state.cloudinary, [key]: value }
          }));
        })
        .toArray();
    }
  }

  handleChange = event => {
    const fieldName = event.target.name;
    this.setState(
      {
        cloudinary: {
          ...this.state.cloudinary,
          [event.target.name]: event.target.value
        }
      },
      () => {
        this.validateField([fieldName]);
      }
    );
  };

  handleBlur = event => {
    const fieldName = event.target.name;
    this.validateField([fieldName]);
  };

  validateField = validate => {
    const errors = { ...this.state.errors };
    let hasError = false;
    validate.forEach(field => {
      if (this.state.cloudinary[field].length === 0) {
        hasError = true;
        errors[field] = `${field} cannot be empty`;
      } else {
        errors[field] = "";
      }
    });
    this.setState({ errors });
    return !hasError;
  };

  handleSubmit = event => {
    event.preventDefault();
    if (
      this.validateField([
        "cloudinary_cloud_name",
        "cloudinary_api_key",
        "cloudinary_api_secret"
      ])
    ) {
      this.props.requestCloudinary(this.state.cloudinary);
      console.log("event", event.target);
    }
  };

  render() {
    const { cloudinary, errors } = this.state;
    const { cloudinaryService } = this.props;
    console.log("cloudinaryService", cloudinaryService);
    let message;
    if (typeof cloudinaryService === "string") {
      message = <div>{cloudinaryService}</div>;
    }
    if (cloudinaryService.size === 0) {
      return (
        <div className="earth-spinning">
          <img src={Spinner} alt="spinner" style={{ margin: "0 auto" }} />
        </div>
      );
    }
    return (
      <div className="container cloudinary">
        <Notification>
          {message && message}
        </Notification>
        <h1>Cloudinary Settings</h1>
        <form onSubmit={this.handleSubmit}>
          <TextFieldGroup
            id="formControlsText"
            name="cloudinary_cloud_name"
            type="text"
            value={cloudinary.cloudinary_cloud_name}
            label="Cloud Name"
            onChange={this.handleChange}
            onBlur={this.handleBlur}
            error={errors.cloudinary_cloud_name}
            required
          />
          <TextFieldGroup
            id="formControlsText"
            name="cloudinary_api_key"
            type="text"
            value={cloudinary.cloudinary_api_key}
            label="API Key"
            onChange={this.handleChange}
            onBlur={this.handleBlur}
            error={errors.cloudinary_api_key}
            required
          />
          <TextFieldGroup
            id="formControlsText"
            name="cloudinary_api_secret"
            type="text"
            value={cloudinary.cloudinary_api_secret}
            label="API Secret"
            onChange={this.handleChange}
            onBlur={this.handleBlur}
            error={errors.cloudinary_api_secret}
            required
          />
          <button className="btn btn-default">Save changes</button>
        </form>
      </div>
    );
  }
}

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

0 个答案:

没有答案