React上的复杂嵌套组件无法正常工作

时间:2020-04-11 22:19:02

标签: javascript reactjs

我是React的新手,我已经四处张望,找不到解释,所有示例都具有基本的简单组件,因此与我的不匹配。

第一件事是,我试图用React制作一个SPA,基本的线框是:

<HEADER> 
<CONTENT> 
<FOOTER>

仅更改页面上的内容。

因此,为了避免在每个组件页面中重复<HEADER><FOOTER>,我找到了一种解决方案,该解决方案使模板具有页眉和页脚,并将内容呈现为模板的子级,因此我得到了此模板:

<HEADER>
    {this.children}
<FOOTER>

并且PAGE变为:

<TEMPLATE>
    {my content here}
</TEMPLATE>

一切正常,只是现在我内容中的所有绑定都停止工作,所以我的任何输入字段都可以工作。

有人知道如何帮助我吗?如果有人能向我解释为什么它不起作用,如何修复或如何重组项目,以便获得所需的功能,我将不胜感激。

谢谢!

以下是我的结构:

(问题出在Perfil组件的render方法上,所有字段都不显示其值或不允许更改值)

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import * as ServiceWorker from './serviceWorker';
import Routes from './router';

import './index.css';
ReactDOM.render(
    <Routes />, document.getElementById('root')
);

ServiceWorker.register();
// router.js
import React from 'react';
import {BrowserRouter, Switch, Route} from 'react-router-dom';

//Pages
import Home from './component/home.component';
import Contact from './component/contact.component';
import Perfil from './component/perfil.component';
import About from './component/about.component';
import NotFound from './component/notfound.component';

const Routes = () => (     
    <BrowserRouter>
        <Switch>
            <Route exact path="/"  component={Home} />
            <Route path="/contact"  component={Contact} />
            <Route path="/perfil"  component={Perfil} />
            <Route path="/about"  component={About} />
            <Route component={NotFound} />
        </Switch>
    </BrowserRouter>
);
export default Routes;
// Perfil module
import React, { Component } from 'react';
import axios from 'axios';

import TemplateA from '../../TemplateA';
import apiUrl from '../../axiosApi';
import './index.css';

class Perfil extends Component{

    constructor(props){
      super(props);

      this.state = {
        loaded:'0',
        message:'',
        name: '',
        email: '',
        phone: '',
      };
    }

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

    getHttp = () =>{
        apiUrl.get(`/user/1/`).then( res => {
            this.setState({
                loaded:1,
                message:'',
                name: res.data.nome,
                email: res.data.email,
                phone: res.data.phone,            
            });
        })
        .catch( error => {
            console.log("error");
            console.log(error);
            this.setState({"message": error});
        });
    }

    componentDidMount() {
      this.getHttp();  
    }

    render() {
      const {name, email, phone } = this.state;

      console.log(name);  // here works
      /*
          After the return this.state neither the declared const works.
      */

      return(
        <TemplateA>
          <div className="formPerfil">
            {
              this.state.menssage !== '' ?  (
                <span color="danger">{this.state.mensagem}</span>
              ):''
            }
            <h2>Perfil</h2>
            <hr />
            <h3>Your data</h3>
            <form name="ddP">
              <fieldset>
                <input type="text" placeholder="Name" required
                    name="name" value={this.state.name} onChange={this.changeHandler}/> 
                <input type="email" placeholder="name@email.com" required
                    name="email" value={email} onChange={this.changeHandler}/>
                <input type="text" placeholder="21900000000" maxLength="11" required
                    name="phone" value={phone} onChange={this.changeHandler} /> <br/>
                <br/>
                <input type="submit" value="Update" />
              </fieldset>
            </form>
          </div>
        </TemplateA>
      );
    }

}

export default Perfil;
// TemplateA
import React, { Component } from 'react';

import Header from './template/header'
import Footer from './template/footer'
import './TemplateA.css'

class TemplateA extends Component{

  constructor(props) {
    super(props);
    this.children = props.children;
  }

  render(){
    return (
      <div className="App">
        <Menu/>
          {this.children}
        <Footer/>
      </div>
    );
  };

};

export default App;

1 个答案:

答案 0 :(得分:2)

class TemplateA extends Component{

  constructor(props) {
    super(props);
    this.children = props.children;
  }

  render(){
    return (
      <div className="App">
        <Menu/>
          {this.children}
        <Footer/>
      </div>
    );
  };

};

与道具交互的唯一时间是在构造函数中。如果道具发生变化,则不会重新运行构造函数,因此您将使用原始子项而不是新子项进行渲染。

无需保存this.children。只需在渲染中直接使用道具:

render() {
  return (
    <div className="App">
      <Menu/>
        {this.props.children}
      <Footer/>
    </div>
  );
};