从同级组件传递数据React

时间:2018-07-28 00:15:57

标签: reactjs

我有一个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

3 个答案:

答案 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将消除由于全局状态而引起的事件冒泡的问题)。