我正在创建一个输入表单,可以在其中将一条数据输入到文本字段中,或使用该字段旁边的按钮随机生成一条数据。
我想对表单上的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>
);
}
}
答案 0 :(得分:2)
将函数作为道具传递给RandomDataButton
。在DataInputForm
中定义函数,并在需要更新时通过从DataInputForm
调用prop函数来使用它在RandomDataButton
中更新状态。
答案 1 :(得分:1)
您似乎正在使用多个组件,因此,在使用多个组件时,强烈建议使用任何中央存储容器,这对于在任何组件中获取所需数据很有用
答案 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"}
/>
有关详细信息,请参见沙箱:)