如何使用React

时间:2017-01-27 22:25:29

标签: javascript reactjs state

我正在构建一个实际上是旋转木马的React组件。

有时候,这个轮播(我称之为幻灯片)将会有表格数据,需要在最后验证和收集。

我在Page.slideData函数中传递了表单问题和附带的输入。我也传递了一个表格的小模式,告诉Slides每个单独的幻灯片应该如何验证。

我的问题是获得对每个输入值的引用。在Slides.collectData函数中,我测试了一个“测试”字符串。但我无法弄清楚如何获取当前输入的值来代替“测试”字符串。我还需要最后的所有表单数据,并在结束时将其传递回父级。

非常感谢任何帮助。

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>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

不要从您的网页传递反应元素,而只需让Slide呈现输入并传递相关的道具,例如type

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

要将此值的值备份到父级(页面或幻灯片,不确定您想要哪个?但是相同的原则),只需从父级传递回调函数,而不是在子级上定义回调。 e.g。

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