仅在按下按钮时将状态添加到另一个组件状态的末尾

时间:2018-12-03 21:35:38

标签: javascript reactjs

我有三个组成部分:

  • PageBuilder-基本上是一种表单,用户可以在其中添加页面名称并选择一些项目。
  • PageList-存储用户在状态下创建的所有页面,并将该状态呈现为列表
  • PageUpdater-从PageBuilder获取表单信息,并将其添加到PageList

当有人单击PageBuilder中的按钮时,PageBuilder会将其状态推送到PageUpdater:

  // PageBuilder

addNewPage = () => {
  let info = {...this.state};
  this.props.callBack(info);
}
render(){
return <button onClick={this.addNewPage}>New Page</button>
}

PageUpdater从PageBuilder接收状态并将其作为道具传递给PageList

// PageUpdater

constructor(props){
super(props);
this.state={
  data: ''
}
 }
 updatePageList = (pageAdded) =>{
  this.setState({data:pageAdded});
 }

render(){
  return(
  <div>
   <PageBuilder callBack={this.updatePageList}/>
   <PageList addToList={this.state.data} />
  </div>
   )
}}

PageList接收props中的对象并将其添加到其自己的状态。然后以列表形式返回该状态

// PageList

constructor(props){
super(props);
this.state = {pages:''};
}

componentWillReceiveProps(nextProps) {
 this.setState({pages: [...this.state.pages, nextProps.addToList]});
}

getPages = () => {
  var pages = []
  for(var key in this.state.pages){
      pages.push(this.state.pages[key].pageTitle)}
  return pages; // Return an array with the names
 }


 render(){
   return(
      <div>
         {this.getPages().map((page, index) => <li key={index}> {page} </li>)}
      </div>
   )
 }}

问题是我正在使用componentWillReceiveProps告诉PageList何时更新其状态。因此,每次道具更改时,PageUpdaters状态都会添加到PageList中。我只希望在用户单击新页面按钮(在PageBuilder中)时发生这种情况。

1 个答案:

答案 0 :(得分:0)

React的主要原则之一是每个状态都由一个组件管理,您可以通过三个组件来更改和管理列表。相反,您的页面列表应该是无状态组件:

 const PageList = ({ pages }) => (<div>
   { pages.map(({ pageTitle }, index) => <li key={index} >{pageTitle}</li> ) }
  </div>);

现在Page应该包含处于其状态的页面,并提供更改它的方法:

 class Page extends React.Component {
   state = { pages: [] };

   addPage = (page) => {
     this.setState(({ pages }) => ({ pages: pages.concat(page) }));
   }

   render() {
     return (<div>
       <PageList pages={this.state.pages} />
       <PageBuilder add={this.addPage} />
     </div>);
   }
}

现在,PageBuilder只需调用this.props.add({ pageTitle: "something" }) ...