【问题标题】:How to manage state of input values with React如何使用 React 管理输入值的状态
【发布时间】:2017-01-27 22:25:28
【问题描述】:

我正在构建一个实际上是轮播的 React 组件。

有时,这个轮播(我称之为幻灯片)将包含表单数据,需要在最后进行验证和收集。

我在 Page.slideData 函数中传递了一个表单问题和随附的输入。我还为表单传递了一个小架构,告诉幻灯片应如何验证每张单独的幻灯片。

我的问题是获取对每个输入值的引用。在 Slides.collectData func 中,我针对“测试”字符串进行测试。但我无法弄清楚如何获取当前输入的值来代替“测试”字符串。最后我还需要所有表单数据,一旦到达终点,我会将其传回给父级。

任何帮助将不胜感激。

class Page extends Component {
  constructor(props) {
    super(props);
    this.slideData = this.slideData.bind(this);
    this.formSchema = this.formSchema.bind(this);
  }
  slideData() {
    return [
        label: `When is this thing?`,
        input: <input type="text" />,
      }, {
        label: 'Will this be private?',
        input: <input type="checkbox" />,
      },
    ];
  }
  formSchema() {
    return [
      { key: 'date', validate: String },
      { key: 'isPrivate', validate: Boolean },
    ];
  }
  render() {
    return (
      <main className="Page">
        <Slides
          data={this.slideData()}
          formSchema={this.formSchema()}
        />
      </main>
    );
  }
}


class Slides extends Component {
  constructor(props) {
    super(props);
    this.state = {
      position: 1,
      qty: this.props.data.length,
      error: null,
    }
    this.cycle = this.cycle.bind(this);
  }
  moveSlides(newPosition) {
    const { qty } = this.state;
    if (newPosition < 1 || newPosition > qty) {
      return;
    }
    this.setState({
      position: newPosition,
      error: null,
    });
  }
  cycle(num) {
    const { position } = this.state;
    const newPosition = position + num;
    if (this.props.formSchema) {
      this.collectData(position, newPosition);
    } else {
      this.moveSlides(newPosition);
    }
  }
  collectData(position, newPosition) {
    const { formSchema } = this.props;
    const currentSlideSchema = formSchema[position - 1];

    const { collectedData } = this.state;
    let newCollectedData = Object.assign({}, collectedData);
    newCollectedData[currentSlideSchema.key] = 'testing';

    if (
      Match.test(
        newCollectedData[currentSlideSchema.key],
        currentSlideSchema.validate
      ) || position > newPosition) {
      this.setState({ collectedData: newCollectedData });
      this.moveSlides(newPosition);
    } else {
      this.setState({ error: "Invalid entry" });
    }
  }
  renderSlides() {
    const { position } = this.state;
    const { data } = this.props;

    return data.map((slide, idx) => {
      const index = idx + 1;
      let alignment;
      if (index === position) {
        alignment = 'active';
      } else if (index > position) {
        alignment = 'right';
      } else {
        alignment = 'left';
      }
      return (
        <Slide
          label={slide.label}
          input={slide.input}
          key={`Slide_${idx}`}
          alignment={alignment}
        />
      );
    });
  }
  render() {
    const { position, error } = this.state;

    return (
      <div className="Slides">
        <div className="Slides_ContentWrapper">
          {this.renderSlides()}
        </div>
        { error &&
          <span className="Slides_Error">{error}</span>
        }
        <div className="Slides_Buttons">
          <button>onClick={() => this.cycle(-1)}>Go back</button>
          <button>onClick={() => this.cycle(1)}>Go Forward</button>
        </div>
      </div>
    );
  }
}

class Slide extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    const { label, input, alignment } = this.props;
    return (
      <div className={`Slide Slide--${alignment}`}>
        <span className="Slide_Label">{ label }</span>
        { input }
      </div>
    );
  }
}

【问题讨论】:

    标签: javascript reactjs state


    【解决方案1】:

    不要从页面向下传递 react 元素,而是让 Slide 呈现输入并传递相关的道具,例如type

    然后您在输入上使用onChange 事件处理程序,它将作为第一个参数传递用户输入。

    要将此值返回给父级(页面或幻灯片,不确定您想要哪个?但原则相同)只需从父级向下传递回调函数,而不是在子级上定义回调。例如

       <Slide
          label={slide.label}
          input={slide.input}
          key={`Slide_${idx}`}
          alignment={alignment}
          onChange={this.onChange}
        />
    

    【讨论】:

    • 这是个好主意,我也想过这样做,但是我需要将其他组件作为道具传递下去,比如 等。所以我确实需要传递下去。
    • @mildrenben 不,你没有。您可以像传递任何其他道具一样将组件作为道具传递
    猜你喜欢
    • 2018-03-13
    • 2020-09-09
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 2020-07-13
    • 2019-11-28
    • 2017-11-26
    • 2020-11-29
    相关资源
    最近更新 更多