React:使用按钮组件生成输入字段数据

时间:2019-06-12 05:14:11

标签: javascript reactjs

我正在创建一个输入表单,可以在其中将一条数据输入到文本字段中,或使用该字段旁边的按钮随机生成一条数据。

我想对表单上的3个字段执行此操作,因此我创建了一个组件 称为<RandomDataButton />

我坚持如何确保按钮组件完成的计算结果更新文本框的值,以便表单提交包含生成的数据。

我不完全了解状态传播,但我了解的是,流程是组件层次结构中的一种方式。

所以我试图做的是选择在文本框中输入一些数据,或者从按钮生成一些随机数据(我想在其他ui创作中重用它)

卡住的地方是如何从层次结构中较低的componenet更新输入字段。

我是否将状态传递给随机发生器按钮,然后让它更新状态副本?还是我完全不喜欢这种方法?

应用程序:

class App extends React.Component {

  render(){
    return (
      <div>
      <DataInputForm />
      </div>
    );
  }
}

DataInputForm:

class DataInputForm extends React.Component{

    state= {
        projectname: '',
        datasource: '',
        data1: '',
        data2: '',
        data3: '',
    };

    handleSubmit = e => {
        e.preventDefault();
        console.log({
            projectname: this.projectname.value,
            datasource: this.datasource.value,
            data1: this.data1.value,
            data2: this.data2.value,
            data3: this.data3.value,
        });
    }

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

    render(){
        return(
            <form className="ui form" onSubmit={this.handleSubmit}>
                <div className="field">
                    <label htmlFor="projectname">Project Name: </label>
                    <input 
                        type="text" 
                        id="projectname"
                        name="projectname"
                        placeholder="Project Name"
                        ref={input => this.projectname = input}
                    />
                </div>
                <div className="field"> 
                    <label htmlFor="datasource">Data Source: </label>
                    <input 
                        type="text" 
                        id="datrasource" 
                        name="datasource" 
                        placeholder="Data Source" 
                        ref={input => this.datasource = input}
                    />
                </div>
                <div className="field">
                    <label htmlFor="data1">Data 1: </label>
                    <input 
                        type="number" 
                        min="3"
                        max="18"
                        id="data1"
                        name="data1"
                        ref={input => this.data1 = input}
                    />                  
                    <RandomDataButton buttonid={"data1button"} buttonname={"Data1"} />
                </div>
                <div className="field">
                    <label htmlFor="data2">Data 2: </label>
                    <input 
                        type="number" 
                        min="3"
                        max="18"
                        id="data2"
                        name="data2"
                        ref={input => this.data2 = input}
                    />                  
                    <RandomDataButton buttonid={"data2button"} buttonname={"Data2"} />
                </div>
                <div className="field">
                    <label htmlFor="data3">Data 3: </label>
                    <input 
                        type="number" 
                        min="3"
                        max="18"
                        id="data3"
                        name="data3"
                        ref={input => this.data3 = input}
                    />                  
                    <RandomDataButton buttonid={"data3button"} buttonname={"Data3"} />
                </div>
                    <button className="ui button" type="submit">Create Data</button>
            </form>
        );
    }
}

RandomDataButton:

const getRandom = max => Math.floor(Math.random() * Math.floor(max));

class RandomDataButton extends React.Component {

    generateData(value){
        var result, destination;
        destination = value.toLowerCase();

        result = getRandom(1000);
        console.log("Generated " + result + " for range of " + value + "]: " + destination);
        //this.state.{destination};
    }

    render(){
        return(
            <button id={this.props.buttonid} type="button" onClick={this.generateData.bind(null,this.props.buttonname)}>{this.props.buttonname}</button>
            //<button id="strbutton" type="button">Generate</button>
        );
    }
}

3 个答案:

答案 0 :(得分:2)

将函数作为道具传递给RandomDataButton。在DataInputForm中定义函数,并在需要更新时通过从DataInputForm调用prop函数来使用它在RandomDataButton中更新状态。

答案 1 :(得分:1)

您似乎正在使用多个组件,因此,在使用多个组件时,强烈建议使用任何中央存储容器,这对于在任何组件中获取所需数据很有用

Fluxredux都是经过测试的用于数据状态管理的体系结构,您可以使用它们中的任何一种,我建议您使用redux。

答案 2 :(得分:1)

以下是一个代码框供您参考:https://codesandbox.io/s/bold-frog-01ff2

这实际上是Amala建议的延续。

您是正确的,层次结构是单向的。这意味着我们应该在DataInputForm(lvl2)中定义一个函数,并将其作为道具传递给RandomDataButton(lvl3)。该函数绑定到DataInputForm的执行上下文,我们想更新它的state,以便可以将新数据反馈回每个单独的输入中。

例如:

  createRandomText = (associatedField, value) => {
    this.setState(
      {
        [associatedField]: value
      },
      () => console.log(this.state)
    );
  };

因此,要正确更新状态,我们需要提供一个与正确输入相对应的字段,以及一个值(随机值)。

我们将该函数作为道具传递给RandomDataButton,并将其用于onClick()处理程序。

class RandomDataButton extends React.Component {
  generateData = () => {
    let result = getRandom(1000);

    this.props.createRandomText(this.props.matchingInput, result);
  };

  render() {
    return (
      <button
        id={this.props.buttonid}
        type="button"
        onClick={this.generateData}
      >
        {this.props.buttonname}
      </button>
      //<button id="strbutton" type="button">Generate</button>
    );
  }
}

此外,我们需要为按钮组件提供另一个道具,以便我们可以正确调用上述函数:

  <RandomDataButton
    buttonid={"data1button"}
    buttonname={"Data1"}
    createRandomText={this.createRandomText}
    matchingInput={"data1"}
  />

有关详细信息,请参见沙箱:)