如何通过单击另一个组件中的按钮来更新组件的状态?

时间:2019-01-14 11:43:01

标签: javascript reactjs

我的React应用程序中有2个组件。在第一次页面加载时,第一个组件应该进行查询并相应显示数据(按钮)。到目前为止,第二个组件的状态为空。当用户单击任何按钮时,应该对服务器提出另一个请求,并且第二个组件的状态应该更改,并且应该反映在网页上。 这些是我的文件。 Apps.js

UPDATE <tablename>
SET start = 'X', end = 'Y';
orgList.js

import React, { Component } from 'react';
import './App.css';

import OrgList from "./orgList"
import OrgDetails from "./orgDetails"
class App extends Component {
  
  render() {
    return [
       <OrgList/>,
       <OrgDetails/>

    ];
  }
}

export default App;

orgDetails.js

import React, { Component } from 'react'
import OrgDetails from "./orgDetails"
var posts =[]

 class OrgList extends Component {
   constructor(props){
     super(props);
     this.state={
     mainpost: [],
     devices:[],
     }
}
     
     componentDidMount(){
         fetch(someURL)
         .then(res => res.json())
         
         .then(function (data){
            for (let i = 0; i < 3; i++){
                posts.push(data.orgs[i].name) 
               } 

         }).then(mainpost => this.setState({mainpost:posts}));
                 
    }
  render() {
      var token =new OrgDetails();
     const postItems =this.state.mainpost.map((post) => (
      console.log(post),
      <button
        data-tech={post}
        key={post}
        className="org-btn"
        onClick={() => token.dispatchBtnAction(post)}
      >
      <h3>{post}</h3>
      </button>
      
    )
    )
    return (
      <div>
        <h3> Organisations!!!! </h3>
        <h5>{postItems}</h5>
      </div>
    )
  }
}
export default OrgList;

但是我收到此警告...

  

警告:无法在尚未安装的组件上调用setState。这是一项禁止操作的操作,但可能表明您的应用程序中存在错误。而是直接分配给import React, { Component } from 'react' var list =[] const orgname = org => `someURL/${org}` class OrgDetails extends Component { state={ devices:[], } constructor(props){ super(props); this.state={ devices: [], } this.dispatchBtnAction=this.dispatchBtnAction.bind(this) } dispatchBtnAction=(str) => { list =[] fetch(orgname(str)) .then(res => res.json()) .then(function (data){ for (let i = 0; i < 3; i++){ //console.log("123") list.push(data.devices[i].location) console.log(list) } }).then(devices => this.setState({ devices : list, })); } render() { const devices=this.state.devices.map((dev,i)=>( <div key={dev}> <li>{dev}</li> </div> )) return ( <div> <p>{devices}</p> </div> ) } } export default OrgDetails;或在OrgDetails组件中定义具有所需状态的this.state类属性。

因此,状态不会更改,组件也不会重新呈现。 如何消除此警告,如果有更好的方法,请提出建议。

2 个答案:

答案 0 :(得分:0)

由于这2个组件不是父子组件,因此也许应该在App中实现所有逻辑,然后将状态处理程序作为对每个组件的支持。 然后您的组件将如下所示:

class App extends Component {
  state = { clicks: 0 }
  incrementState = () { 
    const prev = this.state.clicks;
    this.setState({ clicks: prev + 1 })
  }

  render() {
    return [
       <DisplayComponent counter={this.state.clicks} />,
       <ControlComponent onIncrement={this.incrementState} />

    ];
  }
}

显示状态的组件

class DisplayComponent extends Component{
  render() {
    return (<h3>this.props.counter</h3>);
    }
  }

处理状态的组件

class ControlComponent extends Component {
  render() {
    return (<button onClick={this.props.onIncrement}>click me</button>)
  }
}

答案 1 :(得分:0)

整个问题是这一行var token =new OrgDetails();,这只是创建对象。但不要将其安装在DOM中。它还未引用在<OrgDetails/>中创建的组件App。因此,当您尝试使用token.dispatchBtnAction(post)时,您尝试将setState用于未安装在DOM中的组件上,因此会出现错误。

这是在两个组件之间进行通信的一种非常可疑的方式。您最好在组件之间使用父子关系。另外,您还可以看一下Presentational Component和Container组件的区别,以简化工作流程。阅读此link