简体   繁体   English

在React组件之间移动数据

[英]Moving data between react components

So I'm trying to break the component on my App.js into a smaller component, that being my Sidebar.js. 因此,我试图将App.js上的组件分解为一个较小的组件,即我的Sidebar.js。 I took a small section of the code and put it in its own Sidebar.js file but no matter what I've tried, I cant call my function getNotesRows() from App.js without it being unable to find it or this.states.notes being undefined. 我只花了一小段代码并将其放在自己的Sidebar.js文件中,但是无论我尝试了什么,我都无法从App.js调用我的函数getNotesRows(),除非它无法找到它或this.states .notes未定义。 I just want it to send the code back and forth. 我只希望它来回发送代码。 This is a demo app, so I know it's not the most practical. 这是一个演示应用程序,所以我知道这不是最实用的。

 import React, { Component } from "react"; import classNames from "classnames"; import logo from "./logo.svg"; import checkMark from "./check-mark.svg"; import "./App.css"; import Sidebar from "./components/Sidebar.js"; class App extends Component { constructor(props) { super(props); this.state = { notes: [], currentNoteIndex: 0 }; this.markAsRead = this.markAsRead.bind(this); this.selectNote = this.selectNote.bind(this); console.log("Test started 2.25.19 19:23"); } componentWillMount() { fetch('/notes') .then(response => response.json()) .then( notes => { this.setState({ notes: notes, currentNoteIndex: 0 }) } ) .catch( error => { console.log('Ooops!'); console.log(error); } ); } markAsRead() { this.setState(currentState => { let marked = { ...currentState.notes[currentState.currentNoteIndex], read: true }; let notes = [...currentState.notes]; notes[currentState.currentNoteIndex] = marked; return { ...currentState, notes }; }); } selectNote(e) { this.setState({ currentNoteIndex: parseInt(e.currentTarget.id, 10) }); } getTotalUnread() { let unreadArray = this.state.notes.filter(note => { return note.read === false; }) return unreadArray.length; } getNotesRows() { return this.props.notes.map(note => ( <div key={note.subject} className={classNames("NotesSidebarItem", { selected: this.props.notes.indexOf(note) === this.props.currentNoteIndex })} onClick={this.selectNote} id={this.props.notes.indexOf(note)} > <h4 className="NotesSidebarItem-title">{note.subject}</h4> {note.read && <img alt="Check Mark" src={checkMark} />} </div> )); } // TODO this component should be broken into separate components. render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Notes Viewer Test App</h1> <div> Unread: <span className="App-title-unread-count"> {this.getTotalUnread()} </span> </div> </header> <div className="Container"> <Sidebar /> <section className="NoteDetails"> {this.state.notes.length > 0 && ( <h3 className="NoteDetails-title"> {this.state.notes[this.state.currentNoteIndex].subject} </h3> )} {this.state.notes.length > 0 && ( <p className="NoteDetails-subject"> {this.state.notes[this.state.currentNoteIndex].body} </p> )} {this.state.notes.length > 0 && ( <button onClick={this.markAsRead}>Mark as read</button> )} {this.state.notes.length <= 0 && ( <p> No Notes! </p> )} </section> </div> </div> ); } } export default App; 

Above is my App.js and below is the Sidebar.js that I'm trying to create 上面是我的App.js,下面是我要创建的Sidebar.js

 import React, { Component } from "react"; import "../App.css"; import App from "../App.js"; class Sidebar extends React.Component{ constructor(props) { super(props); } render(){ return ( <section className="NotesSidebar"> <h2 className="NotesSidebar-title">Available Notes:</h2> <div className="NotesSidebar-list">{App.getNotesRows()}</div> </section> )}} export default Sidebar; 

You cannot access a method like that. 您无法访问类似的方法。 You need to pass the method as a prop and use it in the child. 您需要将方法作为道具传递,并在孩子中使用它。

<Sidebar getNotesRows={this.getNotesRows} />

and in Sidebar use 并在补充工具栏中使用

<div className="NotesSidebar-list">{this.props.getNotesRows()}</div>

In your sidebar, you're trying to call getNotesRows() from App, but Sidebar doesn't need access to app (you shouldn't have to import App in Sidebar.js). 在侧边栏中,您尝试从App调用getNotesRows() ,但侧边栏不需要访问该应用(您不必在Sidebar.js中导入App)。 Instead, you should pass the function from App to your Sidebar component, and reference it from Sidebar's props. 相反,您应该将功能从App传递到Sidebar组件,并从Sidebar的props中引用它。

In App.js, you'll need to bind getNotesRows and pass it to sidebar.: 在App.js中,您需要绑定getNotesRows并将其传递到侧边栏。

<Sidebar getNotesRows={ this.getNotesRows } />

Then in Sidebar.js, you'll need to reference getNotesRows in your render method: 然后在Sidebar.js中,您需要在渲染方法中引用getNotesRows

render() {
  const notes = this.props.getNotesRows();
  return (
    <section className="NotesSidebar">
      <h2 className="NotesSidebar-title">Available Notes:</h2>
      <div className="NotesSidebar-list">{ notes }</div>
    </section>
  );
}

似乎这里的问题是您试图将类函数用作静态属性,简单地说,将其导入到侧边栏(?)时尚未初始化App类,因此未找到静态函数。在您的App类上,这样就可以调用App.getNotesRows(),也许您应该重新考虑您的组件,并使用基于组合的编程方法(而不是OO方法)将它们分离在容器组件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM