javascript - 从函数返回的 View 不会在状态更改时更新

标签 javascript node.js reactjs antd

我在react中使用ant design组件,其中我使用了steps组件,该组件使用从数组返回的 View ,在该数组中我使用函数返回 View ,但是 View 第一次正确渲染,但是当状态更改时 View 不会相应更新,另外,如果我使用输入元素,我无法键入这些输入元素,请帮助

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. 无法在输入元素中键入内容

    正是因为 JSX step渲染被分配给firstStepContent直接地。 换句话说,firstStepContent = (JSX)制作firstStepContent无法在每个 React 生命周期中进行更改。

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

    我 fork 了你的codesandbox,并放入 original firstStepContent以上function一个。

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

关于javascript - 从函数返回的 View 不会在状态更改时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57025224/

相关文章:

JavaScript 最佳实践原型(prototype)

javascript - React.js - 如何设置选中/选中的单选按钮并跟踪 onChange?

javascript - 如何在 Sequelize.js 中撤消软删除

javascript - 具有嵌套 Promise 数组的对象

javascript - React autoFocus 将光标设置为输入值的开头

arrays - 在 React JSX 中循环内部循环

javascript - React 组件的自定义类型 - Prop 不匹配

javascript - 如何区分javascript对象中的url和字符串

javascript - 如何在 node.js 中的 for 循环中编写回调函数

node.js - Mongoose 错误: Operation `x.findOne()` buffering timed out after 10000ms