从函数返回的视图在状态更改时不会更新

时间:2019-07-14 06:54:08

标签: javascript node.js reactjs antd

我在react中使用了蚂蚁设计组件,在其中我使用了steps组件,该组件使用了从数组返回的视图,在该数组中我使用了函数来返回视图,但是视图是第一次正确呈现的,但是当状态更改时,视图也不会相应地更新。此外,如果我使用的输入元素无法输入,请帮忙

import React, { Component } from "react";
import { Steps, Button, message, Form, Icon, Input } from "antd";
const { Step } = Steps;

class Register extends Component {
  state = {
    current: 0,
    getFieldDecorator: this.props.form.getFieldDecorator,
    email: "",
    username: "",
    password: "",
    password2: "",
    imageSelected: false,
    imageSource: null
  };

  onChange = e => {
    this.setState({
      imageSource: URL.createObjectURL(e.target.files[0])
    });
  };

  handleSubmit = e => {
    e.preventDefault();
  };

  firstStepContent = (
    <Form className="firstPage" onSubmit={this.handleSubmit}>
      <Form.Item>
        {this.state.getFieldDecorator("email", {
          rules: [{ required: true, message: "Please enter an email" }]
        })(
          <Input
            prefix={<Icon type="user" style={{ color: "rgba(0,0,0,.25)" }} />}
            placeholder="Enter email"
            name="email"
            onChange={this.handleChange}
            type="email"
          />
        )}
      </Form.Item>
      <Form.Item>
        {this.state.getFieldDecorator("username", {
          rules: [{ required: true, message: "Please enter a username " }]
        })(
          <Input
            prefix={<Icon type="user" style={{ color: "rgba(0,0,0,.25)" }} />}
            placeholder="Enter username "
            name="username"
            onChange={this.handleChange}
            type="text"
          />
        )}
      </Form.Item>
      <Form.Item>
        {this.state.getFieldDecorator("password", {
          rules: [{ required: true, message: "Please enter a password " }]
        })(
          <Input.Password
            prefix={<Icon type="lock" style={{ color: "rgba(0,0,0,.25)" }} />}
            placeholder="Enter password"
            name="password"
            onChange={this.handleChange}
            type="password"
          />
        )}
      </Form.Item>
      <Form.Item>
        {this.state.getFieldDecorator("password2", {
          rules: [
            { required: true, message: "Please enter confirmation password" }
          ]
        })(
          <Input.Password
            prefix={<Icon type="lock" style={{ color: "rgba(0,0,0,.25)" }} />}
            placeholder="Confirm password"
            name="password2"
            onChange={this.handleChange}
          />
        )}
      </Form.Item>
    </Form>
  );

  uploadButton = (
    <div>
      <Icon type="plus" />
      <div className="ant-upload-text">Select a profile photo</div>
    </div>
  );

  secondStepContent = (
    <div className="imageUpload">
      <div className="imageBox">
        {this.state.imageSource && <img src={this.state.imageSource} />}
        <input
          className="fileSelect"
          type="file"
          accept="image/*"
          onChange={this.onChange}
          style={{ opacity: "0" }}
        />
        <div className="imageMessage">
          <Icon type="plus" />

          <p>Select an profile image</p>
        </div>
      </div>
    </div>
  );

  thirdStepContent = <div />;

  steps = [
    {
      title: "Login Credentials",
      content: this.firstStepContent
    },
    {
      title: "Profile Image",
      content: this.secondStepContent
    },
    {
      title: "Bio",
      content: this.thirdStepContent
    }
  ];

  next = () => {
    this.setState({
      current: this.state.current + 1
    });
  };

  prev = () => {
    this.setState({
      current: this.state.current - 1
    });
  };

  handleChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  render() {
    const { current } = this.state;
    return (
      <div className="registerComponent">
        <Steps current={current}>
          {this.steps.map(item => (
            <Step key={item.title} title={item.title} />
          ))}
        </Steps>
        <div className="steps-content">{this.steps[current].content}</div>
        <div className="steps-action">
          {current < this.steps.length - 1 && (
            <Button type="primary" onClick={() => this.next()}>
              Next
            </Button>
          )}
          {current === this.steps.length - 1 && (
            <Button
              type="primary"
              onClick={() => message.success("Processing complete!")}
            >
              Done
            </Button>
          )}
          {current > 0 && (
            <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
              Previous
            </Button>
          )}
        </div>
      </div>
    );
  }
}

const WrappedRegisterForm = Form.create({ name: "register" })(Register);

export default WrappedRegisterForm;

1 个答案:

答案 0 :(得分:0)

尝试回答输入的问题。

  1. 无法键入输入元素

    这是因为step渲染的JSX被直接分配给firstStepContent。 换句话说,firstStepContent = (JSX)使firstStepContent在每个反应生命周期中都无法改变。

    要对其进行修复,只需将其更改为功能:firstStepContent =()=> (JSX), 并在渲染阶段调用它: <div className="steps-content">{this.steps[current].content()}</div>

    我分叉了您的密码箱,并将original firstStepContent放在function上方。

    它们将组件状态打印为任一JSX的JSON字符串,因此您可以观察到差异: https://fkbft.codesandbox.io/