我有一个HealthForm组件,用户可以在其中输入文本输入中的URL,然后单击一个按钮进行提交。我已将该网址另存为组件中的状态,并调用了全部可用的一些API。 问题是我还有其他几个需要该url的组件,而我似乎找不到找到将其传递给它们的方法。
我的App.js看起来像这样,这就是为什么所有其他帖子/教程都让我感到困惑的原因。
class App extends React.Component {
render(){
return(
<MuiThemeProvider>
<Router>
<div className="App">
<Route path="/" component={()=>(
<div>
<Header/>
<HealthForm/>
</div>)}/>
<Route path="/path1" component={ProductForm}></Route>
<Route path="/path2" component={xForm}></Route>
<Route path="/path3" component={yForm}></Route>
<Route path="/path4" component={zForm}></Route>
</div>
</Router>
</MuiThemeProvider>
);
}
}
HealthForm
class HealthForm extends React.Component {
constructor(props) {
super(props);
this.state = {
jarvisURL: '',
jarvisURLError: '',
status: '',
showStatus: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
validate = () => {
//…checks for input errors
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
const err = this.validate();
let that = this;
if (!err) {
this.setState({
jarvisURLError: ''
});
console.log(this.state);
var data = this.state.jarvisURL
//… a fetch API call
}
}
render() {
return (
<form>
<TextField
...
/>
<br/>
<Button variant="contained" size="small" color="primary" onClick={e => this.handleSubmit(e)} >
Check
</Button>
<br /> <br />
...
</form>
);
}
}
export default HealthForm;
编辑 决定接受Grim的建议
然而,传奇故事在这里继续存在另一个问题:react page refreshes
答案 0 :(得分:2)
对水平流动的数据不满意,这是正确的,但事实是,在复杂的应用程序中,它通常是不可避免的。这就是为什么React提供Context API的原因。首先,为Jarvis数据创建上下文:
import React from "react";
export const JarvisContext = React.createContext();
export class JarvisProvider extends React.Component {
constructor(props) {
super(props);
this.state = {
url: null,
setUrl: this.setUrl
};
}
render() {
return (
<JarvisContext.Provider value={this.state}>
{this.props.children}
</JarvisContext.Provider>
);
}
setUrl = (url) => {
this.setState({url});
}
}
然后,当您需要访问Jarvis状态(设置或获取状态)时,都可以使用Context.Consumer传递当前状态(可以包括setter方法)。
首先,您需要在JarvisProvider中包装可能使用JarvisContext.Consumer的所有代码。请注意,您还可以将道具传递给提供者以设置初始状态。我经常在App.js组件中全局执行此操作,但是您可以将其放在任何需要的位置。
<JarvisProvider>
<HealthForm />
</JarvisProvider>
然后在HealthForm渲染方法中使用它:
render() {
return (
<JarvisContext.Consumer>
{({url, setUrl}) => {
<form>
<input type="text" value={url} onChange={(e) => setUrl(e.target.value)} />
</form>
}}
</JarvisContext.Consumer>
);
}
请注意,这并非您的功能的精确副本,但应该是一个不错的起点。致敬!
答案 1 :(得分:0)
使用ContextAPI或任何状态管理API,例如redux。
答案 2 :(得分:0)
所以有两种方法可以做到这一点。推荐的方法是Context API或Redux。但是,有时在企业环境中不能使用它(我曾在Redux用作API缓存而不用于存储应用程序内的数据集的地方)。尽管不是最佳实践,但另一个解决方案是事件冒泡。
通过事件冒泡,您可以将函数作为属性传递给子组件,然后将其冒泡到父组件。这是针对几个组件完成的,例如您在onClick
侦听器中传递的MaterialUI Button。使用您的handleClick
函数,您将得到类似的信息:
handleSubmit(event) {
event.preventDefault();
const err = this.validate();
let that = this;
if (!err) {
this.setState({
jarvisURLError: ''
});
console.log(this.state);
var data = this.state.jarvisURL
//… a fetch API call
this.props.jarvisURLUpdated(this.state.jarvisURL);
}
}
jarvisURLUpdated
是调用父函数的函数,您可以根据需要设置父状态。然后,父母可以将URL传递给所需的孩子。
另一个选项是使用本地存储或cookie在浏览器中存储URL并重复使用(惯例也不建议使用)。如果您使用react-router-dom
之类的东西,并在单独的页面上显示信息,则此方法比事件冒泡要好一些(Redux将消除由于全局状态而引起的事件冒泡的问题)。