父子组件结构(ReactJS)

时间:2018-07-28 18:39:21

标签: reactjs components structure

我已经创建了多个处于同一级别的组件,这使我很难在它们之间传递数据。 HealthForm组件具有一个输入字段,该字段接受主机URL,然后在单击按钮时提取到API。所有这些都很好。 我需要的是将该URL传递给所有其他组件(ProductForm,xForm,yForm,zForm ...)。现在,我的后端服务器保存了该URL,但是当多个浏览器正在使用该网页时,这会产生影响。 / p>

我想需要更改的是使HealthForm成为其他Forms的父组件。 但是,我的App.js看起来像这样,其中仅包含路由。单独的HeaderTabs链接到正确的路线...

编辑 该代码现在可以成功保存并将URL传递给其子组件。问题是,当我更新HealthForm中的父状态时,页面会重新渲染。

class App extends React.Component {
  constructor(props) {
        super(props);
        this.state = {
            url: '',

        };
        this.setURL = this.setURL.bind(this);
  }

  setURL(page) {
        this.setState({
            url: page
        });
        console.log("Parent url: " + this.state.url);
  }

 render(){
  return(
    <MuiThemeProvider>
        <Router>
            <div className="App">

                <Route path="/" component={()=>(
                    <div>
                        <Header/>
                        <HealthForm changeUrl={this.setURL} urlProp={this.state.url}/>)}>/>
                    </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 = {
        exampleURL: '',
        exampleURLError: '',
        status: '',
        showStatus: false
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
 }

 validate = () => {
 //…checks for input errors
           }
 shouldComponentUpdate(nextProps, nextState) {
        return nextProps !== nextState;
    }

 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({
            exampleURLError: ''
        });
        console.log(this.state);
        var data = this.state.exampleURL

         fetch('http://somehost/health', {
                    method: 'POST',
                    body: JSON.stringify(data)
                })
                .then((res) => {
                    var promiseStatus = res.text();
                    promiseStatus.then(function (value) {
                        console.log("StatusHA: " + value);
                        that.setState({
                            status: value,
                            showStatus: true
                        });

                        if (that.shouldComponentUpdate(that.state.jarvisURL, that.props.urlProp)) 
                            that.props.changeUrl(that.state.jarvisURL);
                    });
                }).catch((error) => {
                    console.log("Error: " + error);
                });
    }
 }

 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;

所有其他形式与HealthForm非常相似。

我如何重新组织代码以使HealthForm成为父组件?还是将一个全新的父组件以所有形式作为其子组件是一个更好的选择?如果是这样,有什么建议吗?

编辑

我做了Snaz建议的更改,成功将url发送到App的状态,但是现在

 this.props.changeUrl(url);

会导致整个应用刷新吗?

1 个答案:

答案 0 :(得分:0)

为什么不将函数传递给HealthForm,它将更改App状态的属性,并通过更改状态将其刷新并将其发送给其他形式?像这样:

应用程序:

class App extends React.Component {
state = {
    url: ''
}

foobar(page){
    this.setState({
        url: page
    });
}

 render(){
  return(
[code here...]
                    <HealthForm changeUrl={this.foobar}/>
[code there...]
  );
 }
}

然后在handle提交的HealthForm中,您只需调用:

this.props.changeUrl(url);

这应该将页面提供给App,然后您可以按照此处显示的类似方式将此网址传递给其他形式: https://github.com/ReactTraining/react-router/issues/4105