Javascript ReactJs-如何从显示嵌套子组件返回到只显示第一个父组件

Javascript ReactJs-如何从显示嵌套子组件返回到只显示第一个父组件,javascript,reactjs,Javascript,Reactjs,提交表单-父级->结果-父级->演示 -父项->按钮BacktoSearch 我正在尝试学习如何在ReactJs中正确思考并创建单页应用程序 我正在用React构建Wikipedia查看器。在我的组件中,用户输入数据,然后在组件中准备数据。 接下来,它将在组件中显示。当组件处于活动状态时,我将使用搜索窗口隐藏在css中 而组件是最后一个组件的父组件。此组件有一个带有此代码的按钮: import React from 'react'; export default class ButtonBac

提交表单-父级->结果-父级->演示 -父项->按钮BacktoSearch

我正在尝试学习如何在ReactJs中正确思考并创建单页应用程序

我正在用React构建Wikipedia查看器。在我的组件中,用户输入数据,然后在组件中准备数据。 接下来,它将在组件中显示。当组件处于活动状态时,我将使用搜索窗口隐藏在css

组件是最后一个组件的父组件。此组件有一个带有此代码的按钮:

import React from 'react';

export default class ButtonBackToSearch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isBackToggleOn: false};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({isBackToggleOn: true});
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>
          BACK
        </button>
      </div>
    );
  }
}
从“React”导入React;
导出默认类按钮BacktoSearch扩展React.Component{
建造师(道具){
超级(道具);
this.state={isBackToggleOn:false};
//此绑定是使`This`在回调中工作所必需的
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.setState({isBackToggleOn:true});
}
render(){
返回(
返回
);
}
}
现在我有一个严重的谜语。当用户单击BACK按钮且isBackToggleOn为真时,我如何“销毁”所有加载的组件:结果、演示、按钮BackToSearch并返回以准备下一次搜索

我当然可以重新加载页面,但重新加载所有页面(F5)就像作弊一样,对吗

在React中,正确的做法是什么

这是我的提交表单代码:

import React from 'react';
import axios from 'axios';

import Title from './Title';
import Results from './Results';

export default class SubmitForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null,
      value: '',
      display: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  axiosStart() {
    const wikiApiUrl = 'https://en.wikipedia.org/w/api.php?action=opensearch&format=json&origin=*&search=';
    const wikiApiUrlWithQuery = wikiApiUrl + this.state.value;
    axios.get(wikiApiUrlWithQuery) 
      .then(response => {
        console.log('@axiosStart was launched by user!');
        this.setState(Object.assign({}, this.state, { data: response.data }))
      }) 
      .catch(err => {
        console.log('Error: => ' + err);
        this.setState(Object.assign({}, this.state, { data: 'error' }))
      });
    this.setState({display: 'displayNone'});
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    console.log(('An input was submitted: ' + this.state.value));
    // handle change has just updated state
    // now app can start axios with entered query
    // as soon as user submits
    this.axiosStart();
    event.preventDefault();
  }

  render() {
    return (
      <div className="container">
        <div className={this.state.display}>
        <form onSubmit={this.handleSubmit}>
          <label>
            <Title />
            <input className="wiki_query" type="text" value={this.state.value} onChange={this.handleChange} autoFocus />
          </label>
          <button className="btn btn-default" type="submit" value="Submit">Search</button>
        </form>
        </div>
        <Results dataReady={this.state.data} />
      </div>
    );
  }
}
从“React”导入React;
从“axios”导入axios;
从“./Title”导入标题;
从“/Results”导入结果;
导出默认类SubmitForm扩展React.Component{
建造师(道具){
超级(道具);
此.state={
数据:空,
值:“”,
显示:“”
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
axiosStart(){
const wikiApiUrl=https://en.wikipedia.org/w/api.php?action=opensearch&format=json&origin=*&搜索=';
const wikiapirlWithQuery=wikiapirl+this.state.value;
get(WikiapirlWithQuery)
。然后(响应=>{
log('@axiosStart是由用户启动的!');
this.setState(Object.assign({},this.state,{data:response.data}))
}) 
.catch(错误=>{
log('Error:=>'+err);
this.setState(Object.assign({},this.state,{data:'error'}))
});
this.setState({display:'displayNone'});
}
手变(活动){
this.setState({value:event.target.value});
}
handleSubmit(事件){
log(('a input was submitted:'+this.state.value));
//句柄更改刚刚更新了状态
//现在应用程序可以使用输入的查询启动axios
//一旦用户提交
这个.axiosStart();
event.preventDefault();
}
render(){
返回(
搜寻
);
}
}

一种方法是将
按钮BacktoSearch
设置为
SubmitForm
本身的子级。正如您所描述的-它更改了提交表单本身的状态,并且与
演示文稿
结果
组件没有实际联系。在我看来,这是进行这种互动的最干净的“反应”方式

尽管现实生活可能比这复杂一些,您可能会争辩说,由于其他未提及的原因,按钮确实必须是嵌套组件的子组件。在这种情况下,您可以采取两种方法:

  • 使用。在最简单的情况下,只需将SubmitForm实例放在上下文中,并公开方法
    goBack
    。然后访问SubmitFormInstance from调用此方法from按钮并调用此方法

  • 使所有组件都具有强制属性
    父级
    。这样,您将始终能够“向上”浏览层次结构树,并找到您需要的任何父级。之后,按照第1步中的步骤进行操作。这听起来可能有点过分,但可能会派上用场

  • 附言

  • 通过所有组件向下传递处理程序到
    SubmitForm
    中定义的“goBack”函数。这是#2的一个更丑陋的变体,我不建议你这样做,因为它会很快在或多或少更大的项目中污染你的组件属性

  • 我有三个部分
    
    主屏幕
    形式
    结果
    

    MainScreen
    将管理要向用户显示的屏幕:结果、表单或默认值

    BackButton
    将在单击时接受要调用的回调。处理程序将是
    MainScreen
    本身,并将更改要显示的屏幕的状态