使用子组件函数通过父组件/容器将数据传递到redux存储

时间:2017-07-12 15:19:04

标签: reactjs redux react-redux

我是React&的新手Redux所以我很难用简单的英语解释,但我会尽我所能。我有一个父/容器组件,它构成了我的应用程序的主要“页面”。在这个组件中,我正在渲染一个标题和各种字段,如下所示:

enter image description here

我想要实现的是标题字段中的任何用户输入都会反映在标题中当前显示为“无标题练习”的位置。

父组件看起来像这样(为简洁起见,不包括各种导入):

export class DrillCreator extends Component {
  render() {
    return (
      <div>
        <EditHeader />

        <div className="container-fluid max-width-container">
          <InputWithTooltip
            type={'text'}
            placeholderText={'Title'}
            tooltipText={'Title Tooltip'}
            required
          />

          <InputWithTooltip
            type={'textarea'}
            placeholderText={'Summary'}
            tooltipText={'Summary Tooltip'}
          />

          <InputWithTooltip
            type={'file'}
            placeholderText={'Hero Image/Video'}
            tooltipText={'Hero Image/Video Tooltip'}
          />

          <InputWithTooltip
            type={'select'}
            options={['7', '8', '9', '10']}
            placeholderText={'Ages'}
            tooltipText={'Ages Tooltip'}
            required
          />
        </div>
      </div>
    );
  }
}

<InputWithTooltip />组件本质上是一个容器,它提供适当的输入以及工具提示组件:

export default class InputWithTooltip extends Component {
  constructor(props) {
    super(props);
    this.state = {
      textEntered: '',
    };
  }

  render() {
    let input = null;
    if (this.props.type === 'text') {
      input = (
        <TextInput
          placeholderText={this.props.placeholderText}
          updateText={textEntered => this.setState({ textEntered })}
        />
      );
    } else if (this.props.type === 'select') {
      input = (
        <SelectInput
          placeholderText={this.props.placeholderText}
          updateText={textEntered => this.setState({ textEntered })}
        />
      );
    } else if (this.props.type === 'textarea') {
      input = (
        <TextAreaInput
          placeholderText={this.props.placeholderText}
          updateText={textEntered => this.setState({ textEntered })}
        />
      );
    } else if (this.props.type === 'file') {
      input = (
        <FileInput
          placeholderText={this.props.placeholderText}
          updateText={textEntered => this.setState({ textEntered })}
        />
      );
    }

    return (
      <div>
        <InputTooltip tooltipText={this.props.tooltipText} />
        {input}
      </div>
    );
  }
}

正如您所看到的,我有textEntered状态,该状态通过onChange道具传递的updateText函数进行更新。

我已经设置了Redux,以便我可以调用一个调度函数来设置我的reducer中的title字段。如果我简化我的父组件并简单地调用具有<TextInput />道具的updateText组件,这样可以正常工作:

export class DrillCreator extends Component {
  constructor() {
    super();
    this.state = {
      textEntered: '',
    };
  }

  render() {
    return (
      <TextInput
        placeholderText="Title"
        updateText={(textEntered) => {
          this.setState({ textEntered });
          this.props.setDrillTitleAction({ textEntered });
        }}
      />
    );
  }
}

const mapDispatchToProps = dispatch => ({
  setDrillTitleAction: drillCreator => dispatch(setDrillTitle(drillCreator)),
});

export default connect(null, mapDispatchToProps)(DrillCreator);

我遇到的问题是,我想从setDrillTitleAction而不是<InputWithTooltip />致电<TextInput />,因为这是表格中我唯一要做的事情。< / p>

就像我说我是React和Redux的新手一样,所以可能会大量过度复杂或完全忽略这一点,所以任何指针都会非常有用。感谢。

1 个答案:

答案 0 :(得分:2)

您可以将调度函数从容器组件作为prop传递给显示组件,然后在更改值时调用它。

在您的情况下,您需要将setTitleDrillAction作为道具传递给InputWithTooltip,然后在updateText回调中调用。

有一点需要指出的是,您将多次存储文本框值 - 在redux状态和InputWithTooltip状态。您可以选择只使InputWithTooltip成为一个无状态组件,它接收其作为prop的值并将更新发送到redux(通过其父容器,如上所述)。